Pre-Rendering und next.js

Pre-Rendering

Pre-Rendering: beim ersten Laden der React-Anwendung erhält der Browser vorgerendertes HTML, um das Laden / Anzeigen zu beschleunigen

Vorteile:

  • schnellere erste Darstellung
  • reduziert zusätzliche API-Aufrufe am Client
  • einfachere Indexierung durch Suchmaschinen

Pre-Rendering

Beispiel:

Deaktiviere JavaScript in den Einstellungen der Browser-Entwicklertools und besuche reactjs.org - es werden Inhalte angezeigt, auch wenn Teile der Interaktivität nicht funktionieren (z.B. Dropdowns)

Zugänge

  • Static Site Generation (Pre-Rendering statischer Inhalte)
  • Server-side Rendering (Pre-Rendering dynamischer Inhalte)

Static Site Generation

  • sinnvoll, wenn Daten sich nicht oft ändern (z.B. Blog Posts)
  • bei Änderung von Daten muss die Website statisch neu generiert und deployed werden
  • Daten, die sich oft ändern (z.B. Kommentare zu einem Blog Post) wären nicht Teil des Pre-Renderings

Server-side Rendering

  • beim Öffnen einer React-Seite wird diese am Server vorgerendert und zum Client gesendet
  • benötigt node.js am Server

Server-side Rendering und API-Abfragen

Ãœblicher Prozess zum Laden von Daten in einer React-Anwendung:

  • React-Anwendung wird zum Client gesendet
  • Anwendung wird zunächst ohne Daten gerendert
  • Client fragt vom Server Daten an
  • Daten werden zum Client gesendet
  • Anwendung wird neu gerendert

Prozess mit next.js:

  • Daten werden am Server geladen
  • Anwendung wird am Server gerendert
  • Vorgerenderte Anwendung und zugehörige Daten um sie dynamisch zu machen werden zum Client gesendet

Tools

  • gatsby: Static Site Generation
  • next.js: Static Site Generation, Server-side Rendering

Next.js

Next.js

React-Framework mit Unterstützung für:

  • Static Site Generation
  • Server-Side Rendering
  • einfaches Datei-basiertes Routing
  • Backend- / API- Entwicklung im gleichen Projekt

Ressourcen

Die next.js Website hat sehr gute Materialien: https://nextjs.org

Create-next-app

Create-next-app

npx create-next-app@latest
npx create-next-app@latest --ts

Projektstruktur

mögliche Projektstruktur:

  • pages
  • public: statische Assets
  • styles
  • components

Entwicklungsserver

npm run dev

Deployment mit node.js

um einen Produktionsbuild zu erstellen:

npm run build

um ihn zu starten:

npm run start

Deployment auf einem statischen Server

nur möglich, wenn kein server-seitiges Rendering benötigt wird (also kein getServerSideProps)

Ändern des build-Scripts in package.json auf: next build && next export

Ein statischer Build (im Ordner out) wird dann ausgeführt via:

npm run build

(siehe https://nextjs.org/learn/excel/static-html-export)

Seiten und Navigation

Seiten und Navigation

Beispiel einer Seitendefinition:

// pages/index.tsx
import type { NextPage } from 'next';
import Link from 'next/link';
import Head from 'next/head';

const Index: NextPage = () => (
  <div>
    <Head>
      <title>Home</title>
    </Head>
    <Link href="/about">
      <a>About Page</a>
    </Link>
    <p>Hello Next.js</p>
  </div>
);

export default Index;

Seiten und Navigation

besondere Komponenten, die next zur Verfügung stellt:

  • Link: Link innerhalb einer Single-Page-Anwendung
  • Head: Ermöglicht das einfache Setzen von Inhalten des <head>-Elements der Seite

Gemeinsamer Inhalt

definieren von "globalem" Inhalt, der über alle Seiten hinweg gleich ist:

// _app.tsx
function MyApp({ Component, pageProps }: AppProps) {
  return (
    <div>
      {/* fixed header content */}
      <header>header content</header>
      {/* variable content - defined by the route */}
      <Component {...pageProps} />
      {/* fixed footer content */}
      <footer>footer content</footer>
    </div>
  );
}

Seiten und Navigation

Aufgabe: Erstelle weitere Seiten

Pre-Rendering und API-Abfragen

Pre-Rendering und API-Abfragen

definieren von Code, der zu verschidenen Zeiten in next.js ausgeführt wird:

  • Code, der beim Build läuft
  • Code, der am Server läuft
  • Code, der im Browser läuft

Pre-Rendering und API-Abfragen

Beim build werden alle Einträge im Ordner pages vorgerendert

Manche pages werden ohne zusätzlichen Input gerendert, andere sind mit Datenquellen verbunden

Pre-Rendering und API-Abfragen

besondere (asynchrone) Funktionen, die wir aus einer Seitendefinitionsdatei exportieren können:

  • getServerSideProps (läuft bei jedem Request)
  • getStaticProps (läuft während des Builds)

können Daten laden und sie als Props an die Seitenkomponente übergeben

werden jeweils nur auf dem Build-Rechner oder dem Server ausgeführt → können Dateien einlesen oder direkte Datenbankabfragen machen

Funktionalität von fetch ist automatisch durch ein Polyfill vorhanden

Pre-Rendering und API-Abfragen

Beispiel: Seite, die einen zufälligen Witz von einem API lädt

import type { GetServerSideProps, NextPage } from 'next';

type JokeProps = { joke: string };
const Joke: NextPage<JokeProps> = (props) => (
  <article>{props.joke}</article>
);
const getServerSideProps: GetServerSideProps<JokeProps> = async () => {
  const url = 'https://api.chucknorris.io/jokes/random';
  const res = await fetch(url);
  const joke = (await res.json()).value;
  return { props: { joke: joke } };
};

export default Joke;
export { getServerSideProps };

Pre-Rendering und API-Abfragen

Ãœbungen:

Routenparameter

Routenparameter

Wir können aus URLs wie den folgenden Parameter auslesen:

  • /todos/3
  • /todos/?todoid=3

Routenparameter

Routenparameter werden in eckigen Klammern im Dateipfad angegeben, z.B.: pages/todos/[id].js

Routenparameter

dynamisches Abfragen von Routenparametern:

import { NextPage } from 'next';
import { useRouter } from 'next/router';

const TodoDetails: NextPage = () => {
  const router = useRouter();
  return (
    <div>
      <h1>detail view for todo {router.query.id}</h1>
    </div>
  );
};

export default TodoDetails;

Routenparameter

Vorrendern von Seiten basierend auf einem Satz Routenparameter - via getStaticPaths

export const getStaticPaths: GetStaticPaths = () => {
  const paths = [];
  for (let i = 1; i <= 200; i++) {
    paths.push({ params: { id: String(i) } });
  }
  return { paths, fallback: false };
};

getStaticPaths gibt unter dem Namen paths ein Array zurück, das Routen beschreibt - diese werden jeweils an getStaticProps übergeben

Routenparameter

nach der Implementierung von getStaticPaths können wir Seiten mit dynamischen Routen vorrendern

npm run build