Next.js: Statische Generierung / SSG-Verbesserungen

Erstellt am 25. Nov. 2019  ·  250Kommentare  ·  Quelle: vercel/next.js

Zusammenfassung

Ermöglichen Sie, dass Next.js vollständig hybrid wird, indem Sie Methoden für die statische Generierung und das serverseitige Rendering auf Seitenbasis bereitstellen.

  • Zwei neue Methoden zum Abrufen von Daten pro Seite

    • getStaticProps - Melden Sie sich zum Zeitpunkt next build für die statische Generierung (SSG) an.

    • getServerSideProps - Aktivieren Sie das serverseitige Rendering (SSR), das bei Bedarf rendert.

  • Eine neue Methode zur statischen Generierung (SSG) einer Reihe von Routen aus dynamischen Quellen

    • getStaticPaths - Liste der Parameter für dynamische Routen zurückgeben, um statische Generierung (SSG) durchzuführen

Dieser RFC behandelt ausschließlich API-Ergänzungen. Alle neuen Funktionen sind vollständig abwärtskompatibel und können schrittweise übernommen werden. Dieser RFC führt keine veralteten Versionen ein.

Hintergrund

Beim Erstellen von Websites oder Webanwendungen müssen Sie im Allgemeinen zwischen 2 Strategien wählen: Statische Generierung (SSG) oder serverseitiges Rendering (SSR).

Mit Next.js können Sie stattdessen Hybridanwendungen erstellen, mit denen Sie pro Seite auswählen können, welche Strategie verwendet wird. Ab Next.js 9 werden Seiten ohne getInitialProps statisch optimiert und nach next build als .html Dateien ausgegeben.

Möglicherweise möchten Sie jedoch Daten abrufen, während Sie statische Seiten für Ihren speziellen Anwendungsfall generieren.

Zum Beispiel, um statisch Marketingseiten aus einem CMS oder einem Blogbereich der Website zu generieren.

Die Verwendung von getInitialProps würde Sie in diesem Fall für SSR entscheiden.

Next.js verfügt derzeit über einen next export Befehl, der die Anwendung vollständig SSG macht und den hybriden Charakter von Next.js verliert.

Wenn Sie next export mit getInitialProps ein weiteres Problem auf. getInitialProps wird zur Build-Zeit aufgerufen (was großartig ist), aber wenn Sie dann next/link , um zwischen den Seiten zu wechseln, wird getInitialProps clientseitig aufgerufen, anstatt next export Ergebnis.

Dies bedeutet auch, dass die Datenquelle (CMS / API-Endpunkt) bei clientseitigen Übergängen direkt aufgerufen wird. Wenn Ihre Datenquelle ausgefallen ist, werden clientseitige Übergänge beim Wechsel zwischen den Seiten unterbrochen.

Wir haben mit Vielnutzern von SSG und next export in Next.js wie HashiCorp (danke @jescalan) zusammengearbeitet und ausführlich die richtigen Einschränkungen für die Einführung zweier neuer Datenabrufmethoden untersucht: getStaticProps und getServerSideProps . Aber auch eine Möglichkeit, Parameter zum statischen Generieren statischer Seiten für dynamische Routen bereitzustellen: getStaticPaths (Ersatz für exportPathMap pro Seite).

Diese neuen Methoden haben viele Vorteile gegenüber dem getInitialProps Modell, da es einen klaren Unterschied zwischen SSG und SSR gibt.

  • getStaticProps markiert die Seite als statisch zur Erstellungszeit zu generieren (bei Ausführung von next build )
  • getStaticPaths ermöglicht die Rückgabe einer Liste von Parametern, die zur Erstellungszeit für dynamische Routen generiert werden sollen
  • getServerSideProps markiert die Seite, die bei jeder Anfrage serverseitig gerendert wird, und ist dem aktuellen getInitialProps Verhalten bei Verwendung eines Servers am ähnlichsten.

Durch die Trennung dieser Methoden können wir auch das richtige Kontextobjekt bereitstellen, das mit TypeScript eingegeben werden kann. Wenn Sie sich für eine bestimmte Rendering-Strategie entscheiden, erhalten Sie die richtigen Werte, derzeit mit getInitialProps Sie erraten, was auf SSG vs. SSR bei Verwendung von TypeScript verfügbar ist.

Darüber hinaus können wir die verschiedenen Kompromisse klarer dokumentieren, indem wir diese Methoden explizit machen.

Implementierung

Beachten Sie, dass sich alle diese Methoden auf der obersten Ebene der Seitenkomponentendatei befinden und nicht verschachtelt werden können, ähnlich wie getInitialProps .

getStaticProps

Die Verwendung von getStaticProps bedeutet, dass die Seite zur Build-Zeit (SSG) statisch gerendert wird.

Mit dieser neuen Methode können Sie Daten für eine Seite abrufen, die zum Zeitpunkt next build statisch in eine .html Datei generiert wird.

Next.js generiert außerdem automatisch eine JSON-Datei, die das Ergebnis von getStaticProps next build Zeitpunkt

Beim clientseitigen Routing über next/link oder next/router ruft Next.js diese JSON-Datei ab, um die zum Rendern der Seite clientseitig erforderlichen Requisiten abzurufen.

Eigenschaften werden unter einem props Schlüssel zurückgegeben, damit in Zukunft andere Optionen eingeführt werden können.

// pages/index.js

// getStaticProps is only called server-side
// In theory you could do direct database queries
export async function getStaticProps(context) {
  return {
    // Unlike `getInitialProps` the props are returned under a props key
    // The reasoning behind this is that there's potentially more options
    // that will be introduced in the future.
    // For example to allow you to further control behavior per-page.
    props: {}
  };
}

Das context enthält:

  • params - Die Parameter auf einer dynamischen Route.

getStaticPaths

Dies ist eine Erweiterung der getStaticProps Nutzung für dynamische Routen.

getStaticPaths ersetzt die Notwendigkeit eines exportPathMap und funktioniert pro Seite.

Da Sie vielleicht statisch eine Liste von URLs generieren möchten, die einen dynamischen Parameter haben, wie im Beispiel unten a slug . Next.js stellt eine getStaticPaths Methode bereit, die es ermöglicht, eine Liste von URLs zurückzugeben. Da es sich um eine async Methode handelt, können Sie diese Liste auch aus einer Datenquelle wie Ihrem CMS abrufen.

// pages/blog/[slug].js

// `getStaticProps` gets a `params` object holding the dynamic parameters
// For `/blog/hello-world` it would look like `{ slug: 'hello-world }`
export async function getStaticProps({ params }) {
  return {
    props: {}
  };
}

// `getStaticPaths` allows the user to return a list of parameters to
// render to HTML at build time.
export async function getStaticPaths() {
  return {
    paths: [
      // This renders /blog/hello-world to HTML at build time
      { params: { slug: "hello-world" } }
    ]
  };
}

Zurückfallen

In vielen Fällen möchten Sie möglicherweise nicht jede mögliche Route in Ihrer Anwendung zur Erstellungszeit vorrendern (z. B. wenn Sie Millionen von Produkten haben). Aus diesem Grund generiert Next.js automatisch eine fallback Seite, die ein Rendering der Seite ohne Daten ist (damit ein Ladezustand angezeigt werden kann), wenn die Seite noch nicht generiert wurde.

Das genaue Verhalten beim Servieren wird sein:

  • Eingehende Anfrage

    • Next.js prüft, ob der Pfad zur Build-Zeit generiert wurde

    • Wenn der Pfad generiert wurde



      • direkt servieren



    • Wenn der Pfad nicht generiert wurde



      • Dienen Sie den Fallback


      • Next.js rendert die Seite (mit Daten) im Hintergrund und fügt sie der Liste der generierten Seiten hinzu


      • Eine nachfolgende Anfrage an denselben Pfad liefert die generierte Seite


      • Dies stellt sicher, dass Benutzer immer eine schnelle Erfahrung haben und nie langsame TTFB vom Server-Rendering haben, während schnelle Builds und statische Generierungseigenschaften erhalten bleiben



Falls Sie möchten, dass Pfade, die nicht zur Build-Zeit generiert wurden, zu einem 404 führen, ist dies auch möglich, indem Sie fallback: false von getStaticPaths

// `getStaticPaths` allows the user to return a list of parameters to
// render to HTML at build time.
export async function getStaticPaths() {
  return {
    // Opt-out of the described fallback behavior
    fallback: false,
    paths: [
      // This renders /blog/hello-world to HTML at build time
      { params: { slug: "hello-world" } }
    ]
  };
}

getServerSideProps

Bei Verwendung von getServerSideProps wird die Seite nicht statisch generiert (SSG), sondern bei jeder Anfrage an den Server (SSR) bei Bedarf gerendert.

Next.js macht auch automatisch einen API-Endpunkt verfügbar, der das Ergebnis des Aufrufs von getServerSideProps zurückgibt. Dies wird für das clientseitige Routing verwendet.

Beim clientseitigen Routing über next/link oder next/router ruft Next.js diesen exponierten API-Endpunkt ab, um die JSON-Daten abzurufen, die in die Requisiten umgewandelt werden, die zum Rendern der Seite clientseitig erforderlich sind.

Diese Methode ist der aktuellen getInitialProps am ähnlichsten, mit dem Hauptunterschied, dass getServerSideProps immer serverseitig und nicht im Browser ausgeführt wird. Entweder beim serverseitigen Rendering oder beim API-Abruf beim clientseitigen Routing.

Ähnlich wie bei getStaticProps die Eigenschaften unter einem props Schlüssel zurückgegeben.

// pages/index.js

// getServerSideProps is only called server-side
// In theory you could do direct database queries
export async function getServerSideProps(context) {
  return {
    // Unlike `getInitialProps` the props are returned under a props key
    // The reasoning behind this is that there's potentially more options
    // that will be introduced in the future.
    // For example to allow you to further control behavior per-page.
    props: {}
  };
}

Das context enthält:

  • params - Die Parameter einer dynamischen Route
  • req - Das HTTP-Request-Objekt
  • res - Das HTTP-Antwortobjekt
  • query - Die Abfragezeichenfolge (nicht ganz sicher, aber wahrscheinlich erforderlich)

Verfasst von @timneutkens , @Timer , @ijjk , @fades. In Zusammenarbeit mit @rauchg , @jescalan und anderen 🚀

Hilfreichster Kommentar

Die Unterstützung für die Static Site Generation (SSG) der nächsten Generation wurde in Next.js 9.3 als stabil veröffentlicht!

Diese Version enthält auch Unterstützung für den "Vorschaumodus" oder die Möglichkeit, die statisch vorgerenderte Seite zu umgehen und die Seite bei Bedarf für autorisierte Benutzer zu rendern .

Mehr dazu können Sie in unserem Blogbeitrag lesen . Wenn Sie mehr praktische Erfahrung haben , springen Sie direkt in unsere

Alle 250 Kommentare

export async function getStaticProps(context) {
  return {
    // Unlike `getInitialProps` the props are returned under a props key
    // The reasoning behind this is that there's potentially more options
    // that will be introduced in the future.
    // For example to allow you to further control behavior per-page.
    props: {}
  };
}

Ich bin daran interessiert zu sehen, unter welchen Umständen wir zusätzliche Daten zurückgeben müssen, die nicht in props . Ich fand die Inline-Erklärung "um das Verhalten pro Seite weiter zu steuern" etwas vage.

Sieht sehr interessant aus! Wäre er ein Ersatz für getInitialProps oder daneben? Für unseren Anwendungsfall ist die Datenabruf-API beispielsweise ein öffentlicher Dienst. Bei der clientseitigen Navigation erwarten wir also, dass der Client die API-Schicht direkt aufruft, während bei SSR der Server sie aufruft. Würde dieser Anwendungsfall in Zukunft weiterhin mit der vorherigen Methode gelöst werden?

Ich bin daran interessiert zu sehen, unter welchen Umständen wir zusätzliche Daten zurückgeben müssen, die nicht in props . Ich fand die Inline-Erklärung "um das Verhalten pro Seite weiter zu steuern" etwas vage.

Es geht vielmehr darum, die Methode zukunftssicher zu machen, damit wir sie später bei Bedarf erweitern können.

Sieht sehr interessant aus! Wäre er ein Ersatz für getInitialProps oder daneben? Für unseren Anwendungsfall ist die Datenabruf-API beispielsweise ein öffentlicher Dienst. Bei der clientseitigen Navigation erwarten wir also, dass der Client die API-Schicht direkt aufruft, während bei SSR der Server sie aufruft. Würde dieser Anwendungsfall in Zukunft weiterhin mit der vorherigen Methode gelöst werden?

Im Allgemeinen hat dieses Verhalten einige Nachteile, zum Beispiel das Abrufen von Wasserfallen, die aus bestimmten Gebieten der Welt langsam sein können. Der getServerProps Ansatz ermöglicht ein effizienteres Caching der Antwort.

Das sieht wirklich interessant aus! Tolle Idee!

Ich habe jedoch Bedenken bezüglich der Bereitstellung...

Stellen wir uns vor, ich hoste auf Now.
Bei der ersten Bereitstellung ist es offensichtlich, dass die gesamte Anwendung auf der Bereitstellung aufbaut.

Dann ändere ich einige Inhalte im CMS und möchte nur den Neuaufbau von SSG-Seiten auslösen, aber der Anwendungscode hat sich nicht geändert.

Sofort ertönt der Alarm, dass es in diesem Fall, wenn ich den Build auslöse, zwei mögliche Lösungen gibt:

1) Nichts wird neu erstellt, da alles zwischengespeichert wird - kein Code hat sich geändert und blabla.
2) Ich --force es, und jetzt wird "alles" neu erstellt, aber ich habe nur die SSG-Seiten neu erstellt.

_Dies sind nur Hypothesen, da das von den Build-Systemen selbst abhängt - wie bewusst sind sie von Next_

Dies würde wahrscheinlich jede andere Hosting-Lösung betreffen.

Next selbst hat ein .next/cache ... wie würde das damit umgehen?

@joltmode das ist derzeit im Grunde für jeden statischen Site-Generator der Fall. .next/cache wird zwischen Bereitstellungen auf Now beibehalten und wiederverwendet. Denken Sie daran, dass Sie derzeit wahrscheinlich getInitialProps für diesen Fall mit Caching (möglicherweise https://zeit.co/blog/serverless-pre-rendering) verwenden, das dynamisch in einer serverlosen Funktion rendert und dann auf unserem CDN zwischenspeichert Verhalten ist immer noch völlig in Ordnung und funktioniert weiterhin, wenn Sie getServerProps .

Wirklich großartig, würde gut zu unserer Verwendung von Next für Kundenprojekte passen und würde einige Boilerplate-Codes entfernen, die wir herumkopieren.

Eine zu berücksichtigende Sache ist die Benennung von getStaticProps und getServerProps, wenn sie in Zukunft ein { props } und mögliche andere Optionen zurückgeben, wären die *Props dann nicht verwirrend? Vielleicht wären getStaticConfiguration, getStaticSetup, getStaticOptions allgemeiner?

@kibs Die Rückgabewerte beziehen sich immer darauf, wie die Requisiten behandelt werden. Also die Namensgebung ist imo in Ordnung.

Das ist einfach genial! Dies löst jeden Anwendungsfall und jedes Bedürfnis, das ich in letzter Zeit hatte oder an das ich bei der Entwicklung von privaten und professionellen Web-Apps denken konnte. Sie haben mich gerade daran gehindert, meinen eigenen Hybrid-Site-Generator zu starten, danke!

Ich kann mich auch darauf beziehen, dass die neuen Methoden besser sind als die vorherigen getInitialProps() und exportPathMap() , was für mich zunächst etwas verwirrend klang, als ich anfing, Next.js zu verwenden und mich mit SSR / SSG beschäftigte. Der pro-Seiten-Ansatz macht für mich auch mehr Sinn.

Kann es kaum erwarten, das auszuprobieren!

Nur eine Randnotiz: Im letzten Beispiel fehlt meiner Meinung nach getServerProps() ein Parameter context .

Nur eine Randnotiz: Im letzten Beispiel fehlt meiner Meinung nach getServerProps() ein Kontextparameter.

Fest!

Das hört sich toll an! Ich frage mich nur aus der Perspektive eines TypeScript-Benutzers, ob getStaticProps , getStaticPaths und getServerProps als statische Methoden in der Seitenkomponente (wie derzeit getInitialProps ) wären einfacher zu tippen / richtig zu verwenden.

const Page: NextPage<Props> = (props) => ...

// Explicit types needed here
export const getStaticPaths: NextGetStaticPaths<Params> = () => ...
export const getStaticProps: NextGetStaticProps<Props, Params> = (context) => ...
export const getServerProps: NextGetServerProps<Props> = (context) => ...

export default Page

// vs.

const Page: NextPage<Props, Params> = (props) => ...

// Static method types come from NextPage<Props, Params>
Page.getStaticPaths = () => ...
Page.getStaticProps = (context) => ...
Page.getServerProps = (context) => ..

export default Page

@herrstucki Das Problem bei diesem Ansatz ist, dass es erheblich schwieriger wird, Bäume zu schütteln (

@timneutkens guter Punkt … aber wäre dann eine separate Datei nicht noch sinnvoller? Oder ist so etwas _zuverlässig_ baumschüttelbar?

// This should all be removed in client-side code …
import {fetchQuery, queryTag} from 'big-data-fetching-lib';
const query = queryTag`...`
export const getStaticProps = async () => ({ props: await fetchQuery(query) })

// Only this should be included client-side
export default (props) => ...

@herrstucki wir können das zuverlässig

Sieht sehr interessant aus! Wäre er ein Ersatz für getInitialProps oder daneben? Für unseren Anwendungsfall ist die Datenabruf-API beispielsweise ein öffentlicher Dienst. Bei der clientseitigen Navigation erwarten wir also, dass der Client die API-Schicht direkt aufruft, während bei SSR der Server sie aufruft. Würde dieser Anwendungsfall in Zukunft weiterhin mit der vorherigen Methode gelöst werden?

Im Allgemeinen hat dieses Verhalten einige Nachteile, zum Beispiel das Abrufen von Wasserfallen, die aus bestimmten Gebieten der Welt langsam sein können. Der getServerProps Ansatz ermöglicht ein effizienteres Caching der Antwort.

Sicher, aber ich spreche davon, die RTT zum Reaktionsserver überhaupt zu vermeiden. Betrachten Sie den Fall, in dem die SSR-Ausgabe vom Server beim CDN/Cache-Server-Proxy zwischengespeichert wird. In Verbindung mit dem Datenabruf für die Client-Navigation, der direkt eine andere API-Schicht aufruft (üblich für Web/Apps/alle Clients), bedeutet dies, dass die Next.js-Serverschicht in einem Szenario mit hohem Datenverkehr nicht so stark skaliert werden muss.

Ich verstehe Ihren Standpunkt zu Wasserfall-Abrufen, aber wenn Sie den Verbrauchern die Möglichkeit geben, den Next-Server als SSR-Schicht im Vergleich zu einer Datenquelle zu behandeln, würden viel bessere Skalierungskonfigurationen ermöglicht.

Sieht sehr interessant aus! Wäre er ein Ersatz für getInitialProps oder daneben? Für unseren Anwendungsfall ist die Datenabruf-API beispielsweise ein öffentlicher Dienst. Bei der clientseitigen Navigation erwarten wir also, dass der Client die API-Schicht direkt aufruft, während bei SSR der Server sie aufruft. Würde dieser Anwendungsfall in Zukunft weiterhin mit der vorherigen Methode gelöst werden?

Im Allgemeinen hat dieses Verhalten einige Nachteile, zum Beispiel das Abrufen von Wasserfallen, die aus bestimmten Gebieten der Welt langsam sein können. Der getServerProps Ansatz ermöglicht ein effizienteres Caching der Antwort.

Sicher, aber ich spreche davon, die RTT zum Reaktionsserver überhaupt zu vermeiden. Betrachten Sie den Fall, in dem die SSR-Ausgabe vom Server beim CDN/Cache-Server-Proxy zwischengespeichert wird. In Verbindung mit dem Datenabruf für die Client-Navigation, der direkt eine andere API-Schicht aufruft (üblich für Web/Apps/alle Clients), bedeutet dies, dass die Next.js-Serverschicht in einem Szenario mit hohem Datenverkehr nicht so stark skaliert werden muss.

Ich verstehe Ihren Standpunkt zu Wasserfall-Abrufen, aber wenn Sie den Verbrauchern die Möglichkeit geben, den Next-Server als SSR-Schicht im Vergleich zu einer Datenquelle zu behandeln, würden viel bessere Skalierungskonfigurationen ermöglicht.

Ich glaube, Sie missverstehen, dass dieses neue Verhalten bedeutet, dass Sie tatsächlich die vollständigen Ergebnisse auf einem CDN zwischenspeichern können, da das CDN dynamische Antworten unterstützt. Dies war bisher mit getInitialProps nicht zuverlässig möglich.

@timneutkens Ich habe mit babel-plugin-preval Code nach getStaticProps zu portieren. Ich habe ein Problem mit fs .

Ich versuche, die .md-Dateien meines ./pages/blog/ Verzeichnisses zu lesen und sie zu durchlaufen, damit ich eine Blog-Indexseite mit all meinen Beiträgen erstellen kann

import React from 'react';
import Link from 'next/link';
import fs from 'fs-extra';

const Index = ({ posts }) => (
  <div>
    Hello World. <Thing msg="hello" />
    <Link href="/thing">
      <a>About</a>
    </Link>
    {posts.map(p => (
      <div key={p.title}>{p.title}</div>
    ))}
  </div>
);

Index.getStaticProps = async () => {
  const items = await fs.readdir('./pages/blog');
  items.forEach(path => /* .... do some stuff ... */ )
  return { props: { posts: items } };
};

export default Index;

Dieser Code führt zu diesem Fehler:

Module not found: Can't resolve 'fs' in '/Users/jared/Downloads/nextjs-typescript-template/node_modules/fs-extra/lib'

IIRC von Razzle, dieser Fehler hat mit den Dateisystem-Stubs von Webpack (oder deren Fehlen) zu tun. Ich glaube, ich habe dies einmal mit Razzle behoben, indem ich dies zur Webpack-Konfiguration hinzugefügt habe.

node: {
  fs: "empty";
}

Ich habe diese next.config.js ausprobiert, aber der Fehler verschwindet einfach. Es scheint jedoch, dass fs / fs-extra nicht wirklich funktioniert, oder es funktioniert und möglicherweise Pfade nicht (mir unklar). Irgendwelche Gedanken dazu?

Meine andere Frage im Allgemeinen ist, was Sie sich für die besten Praktiken für die Verwendung von import vs. require in getStaticProps vorstellen. Wenn ich mich nicht irre, versucht mein obiges Snippet, fs-extra in React isomorph?? zu importieren. Wäre es daher besser, den Import in einen Inline-Requirement wie diesen zu ändern?

js Index.getStaticProps = async () => { const fs = require('fs-extra'); // only require when needed at SSG const props = await fs.readdir('./pages/blog'); return { props: { posts } }; };

Ich glaube, Sie missverstehen, dass dieses neue Verhalten bedeutet, dass Sie tatsächlich die vollständigen Ergebnisse auf einem CDN zwischenspeichern können, da das CDN dynamische Antworten unterstützt. Dies war bisher mit getInitialProps nicht zuverlässig möglich.

Ah, ich glaube ich verstehe was du meinst. Würde das bedeuten, dass getServerProps bei der ersten SSR-Generation einen eindeutigen Endpunkt erstellen würde, in einem inhaltsadressierbaren Hash vielleicht in der URL, die wir dann auf dem CDN zwischenspeichern können? Der einzige Nachteil wäre, dass der Cache nicht zwischen Nicht-Next-Apps (Android / iOS) und Next-Apps geteilt werden kann. Außerdem sind bei einer externen Datenquelle die Cache-Steuerungsanweisungen vorgelagert, aber hier, da Next die Verantwortung für die Bereitstellung der Daten übernehmen würde, benötigen wir APIs oder Requisiten, um diese für die generierten Datenendpunkte anzugeben.

@jaredpalmer Ich https://github.com/zeit/next.js/issues/9524#issuecomment -558628066 (einschließlich meiner Bedenken bezüglich zuverlässiger Baum-Shakeability ) durch eine separate Datei gelöst würde, die vollständig getrennt von kompiliert würde Client-Bundle-Code? Z.B

pages/
    foo.js
    foo.data.js (<- exports getStaticProps etc.)

or:

pages/
    foo.js
pages-data/
    foo.js (<- exports getStaticProps etc.)

@jaredpalmer Tree Shaking wurde auf

Wie immer danke für alles, was ihr tut. Die Arbeit mit Next.js war eine absolute Freude, und wie ich bereits sagte, können wir mit fast jedem Feature-Release die Größe der von mir verwalteten Codebasen _reduzieren_. Es ist wunderbar.

Es ist schwer, diesen RFC kritisch zu sehen, da er, wie geschrieben, für viele Anwendungen sofort nützlich ist. Ich möchte jedoch eine Zeile ansprechen, bei der ich nicht sicher bin, ob ich damit einverstanden bin:

" getStaticPaths ersetzt die Notwendigkeit eines exportPathMap und funktioniert pro Seite."

Bei einigen Anwendungen ist es entweder unpraktisch oder unmöglich, die Routen zum Zeitpunkt der Erstellung zu kennen. Ein paar Beispiele wären:

  • Benutzerprofilseiten
  • Produktseiten (für Unternehmen mit einem sich schnell ändernden Inventar)
  • Seiten mit Verkaufsauftragsdetails

Routen für Seiten wie diese haben wahrscheinlich die Form /entity-name/entity-id und die dynamischen Routen von Next funktionieren wirklich sehr gut, da Sie Dinge wie router.push('/customers/[customerId]', '/customers/baer') tun können. Es gibt noch einen Haken. Wenn Sie vorhaben, diese Dateien statisch mit etwas wie Serve, Netlify, NGINX usw. bereitzustellen, müssen Sie eine Reihe von Weiterleitungen generieren, damit Benutzer beim Seitenaktualisieren keinen 404-Fehler erhalten brauche exportPathMap .

Folgendes wird fast unverändert aus einer Codebasis kopiert, an der ich regelmäßig arbeite:

const buildServeConfig = redirects => {
  const config = {
    public: `dist`,
    trailingSlash: true,
    rewrites: redirects
  };

  const outputPath = `${__dirname}/serve.json`;

  fs.writeFile(outputPath, JSON.stringify(config, null, 2), err => {
    if (err) {
      throw err;
    }
    // eslint-disable-next-line no-console
    console.log(`Generated: ${outputPath}`);
  });
};

...

exportPathMap: function(defaultPathMap, { dev, outDir }) {
  const redirects = Object.entries(defaultPathMap)
    // No need to create a redirect rule for `/dirname/` or `/dirname/index.html`
    .filter(([url]) => url !== `/` && url !== `/index`)
    .map(([url, { page }]) => ({
      // Replaces /[customerId] with /:customerId
      source: url.replace(/]/g, ``).replace(/\[/g, `:`),
      destination: `${page}/index.html`
    }));

  // By default, the routes are sorted such that a route like `/order/:orderId`
  // comes before `/order/new`. Since the `:orderId` portion of `/order/:orderId` 
  // is a wildcard, the route `/order/new` will be a match and consider `new` 
  // as a value for `:orderId`. To get past this, we sort the redirects by the 
  // number of parameters in ascending order.
  const sortedRedirects = [...redirects].sort(
    (currentRedirect, nextRedirect) =>
      currentRedirect.source.split(`:`).length >
      nextRedirect.source.split(`:`).length
  );

  buildServeConfig(sortedRedirects);

  return defaultPathMap;
}

Ich verstehe, dass dieser RFC keine APIs veraltet oder entfernt, und ich erkenne auch an, dass es möglich ist, diese Weiterleitungen durch das Durchlaufen des Build-Verzeichnisses zu erstellen. Selbst wenn es veraltet wäre, habe ich eine schöne Fluchtluke. Aber es "beseitigt die Notwendigkeit von getStaticPaths nicht ganz".

Nochmals vielen Dank für Ihre Aufmerksamkeit bei der Durchführung dieses Projekts

Schließen sich getStaticProps / getStaticPaths und getServerProps gegenseitig aus? zB wäre es möglich, einen Teil gleichzeitig vorgerendert und einen Teil dynamisch zu haben?

Ja, sie sind eine statische Generierung und eine serverseitige Rendering.

Dies behebt eines der großen Dinge, die ich von Gatsby vermisse, bevor wir zu Next migriert haben:

Wir haben eine monolithische (100 kbs) JSON-Datei, aus der wir Daten ziehen, um unsere Seiten zu rendern, die sich nie ändern. In Gatsby haben wir die JSON-Datei in das GraphQL-Schema geladen und danach abgefragt, wobei wir nur die Daten erfasst haben, die wir zum Rendern einer bestimmten Seite benötigten. Mit Next ist der einfachste/sauberste Weg, dies zu tun, import monolith from './monolith.json' , was erfordert, dass der Benutzer die gesamte JSON-Datei herunterlädt.

Dieser RFC befasst sich zu 100% mit diesem Anwendungsfall und bringt Next einen Schritt näher an Gatsby in den Bereichen, in denen Gatsby glänzt (offensichtlich kann Gatsby kein Runtime-SSR ausführen, also spreche ich nur von statischen Buildtime-Renderings).

@timneutkens , danke für den RFC!

Ich habe einen Anwendungsfall für Next.js, den ich kürzlich mit @rauchg besprochen habe.

Next.js liefert sehr flüssiges DX und einige vernünftige Standardeinstellungen. Ich bin also daran interessiert, Next.js für eine clientseitig gerenderte Anwendung zu verwenden, eine Smart-TV-App.

Smart-TV-Apps sind fast klassische Web-Apps, die von der Browser-Engine von TV ausgeführt werden:

  1. Die App ist in einem Bundle verpackt: Stile, Skripte, Bilder, _index.html_, Zertifikate und TV-Konfigurationsdatei.
  2. Das Bundle wird zur Überprüfung an den App Store der Plattform gesendet.
  3. Das Bundle wird dann als App aus dem Store installiert und vom Benutzer ausgeführt.

Die Sache ist, dass das Bundle statisch vom TV-Gerät selbst gehostet und nicht vom Server geladen wird. Daher ist keine SSR-Option möglich (Node.js wird Entwicklern für diese Zwecke nicht zugänglich gemacht). Aber die App selbst ist dynamisch (sagen wir Netflix).

Wir müssen also ein SPA ausführen, das von einem statischen Webserver gehostet wird.

Wie ich verstehe, wird die vollständige Abmeldung von getServerProps (oder getInitialProps ) dazu beitragen, SSR zu vermeiden. Aber was passiert mit dynamischem Rendering auf dem Client? Und wie sieht es in diesem Fall mit dem Routing aus? Laut diesem RFC wurde das Problem noch nicht angegangen. @timneutkens , könnten Sie bitte den besten Weg vorschlagen, um das clientseitige Rendering in Next.js zu aktivieren? Und ob es überhaupt zu Next.js passt? Vielen Dank!

PS Ich kann ein Problem für diesen Anwendungsfall erstellen, wenn Sie der Meinung sind, dass es besser ist, es separat zu besprechen.

@grushetsky können Sie ein anderes Problem erstellen. Das ist eine ganz andere Frage als im RFC diskutiert wird 👍

@timneutkens Das Versprechen dieses RFC ist eines der Dinge, die mich auf Next sehr aufgeregt haben! Nur um das klarzustellen, getInitialProps würde auch noch existieren, oder?

Richtig @outdooricon -- getInitialProps wird es auf absehbare Zeit geben.

Laut RFC:

Dieser RFC behandelt ausschließlich API-Ergänzungen. Alle neuen Funktionen sind vollständig abwärtskompatibel und können schrittweise übernommen werden. Dieser RFC führt keine veralteten Versionen ein.

Toller RFC, super aufgeregt dafür!

Ich habe über die getServerProps in Bezug auf einen bestimmten Anwendungsfall nachgedacht und die Ergebnisse in einem Cache abgelegt. Da dies in einen API-Endpunkt umgewandelt und das Ergebnis als Requisiten an die Komponente geliefert wird, gibt es eine vorgeschriebene Möglichkeit, das Ergebnis in einen externen Cache wie Redux, GraphQL-Caches usw. usw. clientseitig zu legen?

Wenn ich getInitialProps richtig verstehe, da es statisch und asynchron ist, hat Next die Möglichkeit zu warten, bis es abgeschlossen ist, bevor die Komponente zum ersten Mal gerendert wird. Damit können wir dort Dinge in einen externen Cache legen. Dies wird bei getServerProps nicht der Fall sein, da es auf dem Server läuft und das Ablegen von Dingen in einen Cache im Komponentenlebenszyklus zu bedeuten scheint, dass wir ein Rendering haben müssen, bei dem die Daten noch nicht im Cache verfügbar sind , auch wenn es in Requisiten verfügbar ist?

Dies kann natürlich beabsichtigt sein und ich könnte einen Ansatz übersehen, aber ich dachte, ich würde fragen, ob es etwas ist, das in Betracht gezogen wurde?

Bearbeiten: Ich denke, das gilt auch für getStaticProps . 😄

Vielleicht habe ich es irgendwo übersehen, aber wie gehen wir mit Situationen um, in denen Inhalte zwischengespeichert, aber in der DB aktualisiert oder ein neuer Blogbeitrag erstellt wird? Ist ein automatischer Neubau erforderlich? Ich denke schon.

Zuerst! Toller Vorschlag, es ist eine massive Verbesserung gegenüber exportPathMaps im Anwendungsfall der meisten Leute. Es wird wirklich geschätzt. Vor diesem Hintergrund fällt es mir schwer zu verstehen, wie wir es mit der Internationalisierung der Route schaffen können.

Gibt es Vorschläge zum Umgang mit i18n-präfixierten Routen? Mein spezifischer Anwendungsfall erfordert, dass einige Tausend auf Seiten mit unterschiedlichen Länder-Langpräfixen und URLs erstellt werden.

/nl/brillen
/gb/glasses
/es/gafas
...

Es scheint, dass getStaticPaths wirklich hilfreich ist, wenn das Präfix für die URL bekannt ist, wie in Ihrem Beispiel (mit /blog/[id].js ). Aber wie sieht Ihrer Meinung nach eine getStaticPaths Implementierung aus, wenn sie Pfade auf Stammebene generieren muss, mit einem dynamischen Präfix (Landessprache) und einem dynamischen Pfad?

@reaktivo pages/[lang]/blog/[id].js -> in getStaticPaths alle URLs zum statischen Rendern angeben.

@timneutkens Irgendeine Idee, wann dies verfügbar / testbar sein wird?

Im Allgemeinen geben wir keine ETAs heraus, da wir Funktionen ausgiebig mit Produktions-Apps testen, um sicherzustellen, dass die Lösung richtig ist.

Diese Verbesserungen werden mich dazu bringen, mein "nicht so gepflegtes" phänomenales Projekt (reagieren Sie ssg, das niemand außer mir verwendet) völlig veraltet. Toll zu sehen, dass Next.js diese fehlenden Teile hinzufügt!

Ich möchte einen Zweifel klären. Betrachten Sie die Verwendung eines CMS wie WordPress. Nach meinem Verständnis würde ich mit der getStaticPaths-Methode alle Beiträge holen und eine Liste übergeben wie:

export async function getStaticPaths () {
  return [
    // This renders / blog / hello-world to HTML at build time
    {params: {slug: "hello-world"}}
  ];
}

Der Slug jedes Beitrags würde in der Methode getStaticProps verwendet, um den Inhalt abzurufen.
Dies würde in npm build passieren.
Meine Frage bezieht sich auf neue Beiträge, die nach dem Build hinzugefügt werden.
Würde die Methode getStaticProps verwendet werden, um diesen neuen Beitrag per Slug abzurufen?
Wird dieser neue Beitrag eine .html-Datei wie die im vorherigen Build enthalten?
Ich liebe es, mit weiter zu arbeiten und in mehreren Projekten habe ich das sehr gut.

Nichts direkt damit verbunden, aber der Support kann mir keine Antwort geben, die meiner Frage entspricht.

Was Sie hier vorschlagen, könnte die Lösung sein, aber in der Zwischenzeit kann ich nextJS nicht dazu bringen, einen JAMSTACK basierend auf Webhooks-Änderungen zu erstellen.

Wenn ich getInitialProps hätte, werde ich vom Server gerendert.
Wenn ich dies nicht tue, bin ich nur CDNisiert, aber ohne Vorrendern nicht? Und die Seite bleibt ohne Inhalt, solange XHR nicht zurückgekehrt ist (Bye-Bye SEO)

Haben Sie jetzt ein laufendes Beispiel von Jamstack mit nextJS und wir könnten es auf netlify tun.

Vielen Dank,
Andréas

Hey @ScreamZ - diese Änderung ist meiner Meinung nach der Grund dafür, dass mit nextjs eine vollständig statische Site erstellt werden kann. Wir konnten eine nextjs Website statisch kompilieren Verwendung von next export für eine lange Zeit, aber es wäre immer noch Daten auf Client-seitige Strecke Übergängen holt mit getInitialProps . Mit der Möglichkeit, getStaticProps , können Sie clientseitige Übergänge ausführen, ohne dass zusätzliche Daten abgerufen werden müssen – alle abgerufenen Daten in getStaticProps einmal zur Build-Zeit abgerufen und nicht auf Ihrem Live-Site, es sei denn, Sie erstellen erneut. Dies ist die klassische Architektur datengesteuerter statischer Sites. Verknüpfen Sie Ihre Datenquelle über einen Webhook mit Ihrem Host, und wenn sich die Datenquelle ändert, weisen Sie den Host an, Ihre Site neu zu erstellen.

Es gibt viele existierende Beispiele für vollständig statische nextjs-Websites, und es ist trivial, eine nextjs-Site auf netlify zu betreiben. Die Website meiner Firma läuft derzeit auf nextjs und wird von netlify gehostet, hoffentlich dient dies als gutes Beispiel.

Es ist sehr erwähnenswert, dass auch der Hosting-Service von zeit stark in Betracht gezogen werden sollte. Die Preise sind ziemlich ähnlich und ihre Integration mit nextjs-Sites ist unübertroffen - Sie müssen buchstäblich nicht einmal etwas konfigurieren, Sie verknüpfen einfach github und das Hosting von zeit erkennt, dass Sie nextjs ausführen, und konfigurieren und implementieren automatisch alles.

Dies ist keine Werbung, ich arbeite nicht für zeit, sondern nur eine echte Empfehlung. Sie können es mit netlify absolut zum Laufen bringen, und ich habe persönlich für mehrere Websites als Beweis. Sie müssen jedoch gründlich verstehen, wie nextjs funktioniert, und Sie müssen sicherstellen, dass alles richtig konfiguriert ist, damit es auf netlify reibungslos läuft. Wenn Sie nach dem einfachsten und narrensichersten Hosting für eine nextjs-Site suchen, würde ich das Hosting von zeit ausprobieren.

@jescalan Danke für dieses tolle Teilen 🙏🏻

Ich habe kein Problem mit NextJS mit netlify, weil Sie Publish directory , um den Ordner out anzugeben. Aber auf zeit Jetzt gibt es keine Möglichkeit zu sagen, bitte benutze kein SSR, sondern gehe voll auf statisch mit next export .

@ScreamZ das ist irgendwie wahr, aber es hängt davon ab, wie genau Sie eine "vollständige statische" Site definieren. Wenn Sie getStaticProps für alle Ihre Seiten mit dem Hosting-Service von zeit verwenden, entspricht das, was Sie erhalten, effektiv einer statischen Site, auch wenn sie nicht next export läuft, da alle Seiten mit getStaticProps werden nur erstellt, wenn die Site bereitgestellt wird, und werden danach direkt vom CDN bereitgestellt.

Der wesentliche Unterschied besteht darin , dass, soweit ich weiß , dass es nicht einen Weg gibt , um alle Seiten zu zwingen , statisch auf zeit Hosting (edit zu sein: zeit vor kurzem es so geändert , dass jede Seite mit einer Config , die enthält exportPathMap laufen eine vollständig statische Site, daher ist dies nicht mehr der Fall). Seiten mit getStaticProps verhalten sich genauso wie Seiten, die mit next export generiert wurden – eine einzelne statische Kopie der Seite wird bei jedem Treffer direkt vom CDN bereitgestellt. Sie könnten aber auch einige Seiten mit getServerProps oder getInitialProps ausführen und sie würden sich wie vom Server gerenderte Seiten verhalten. Persönlich sehe ich dies als Vorteil - wenn eine SSR-Route erforderlich ist, können Sie einfach eine andere Datenabrufmethode verwenden, und diese einzelne Route ist jetzt SSR, während alle Ihre anderen Routen statisch bleiben können.

@jescalan Danke,

Also müssen Sie nur warten, bis dies implementiert ist, und verwenden Sie in der Zwischenzeit netlify für statische

Gibt es eine Geschichte rund um die SSG-Konfiguration? Insbesondere möchten wir gemeinsam genutzte Build-Artefakte verwenden, aber next export mit anderen Konfigurationen für QA/Prod ausführen. Diese Konfigurationswerte würden nur in getStaticProps gelesen werden. Würde dies serverRuntimeConfig oder publicRuntimeConfig oder process.env direkt verwenden?

@ScreamZ @jescalan Ich habe heute zusammen mit @Timer Zero-Config next export Support auf Now gelandet (er verdient alle Credits). Du kannst tun:

"build": "next build && next export"

Und es wird automatisch funktionieren.

Lass mich wissen wie es gelaufen ist

Ja, ich war der Typ, der beim Support nachgefragt hat und sie haben mir gesagt, dass dies noch implementiert wurde 😅 Soweit ich sehen kann, müssen Sie eine Export-Map in der Konfiguration definieren?

@ScreamZ nein, Sie können einfach next build && next export wie oben gezeigt hinzufügen und es wird funktionieren.

@timneutkens Wenn ich getInitialProps durch getServerProps ersetze, muss ich dann noch target: 'serverless' zur Konfigurationsdatei hinzufügen, um Server Pre Rendering zu aktivieren? Vielen Dank.

Wie können wir diese ausprobieren?

Wie können wir diese ausprobieren?

Ich denke, alle diese Methoden benötigen derzeit das Präfix unstable_ , um erkannt zu werden.

zB unstable_getStaticProps

@timneutkens

@ScreamZ @jescalan Ich habe heute zusammen mit @Timer Zero-Config next export Support auf Now gelandet (er verdient alle Credits). Du kannst tun:

"build": "next build && next export"

Und es wird automatisch funktionieren.

Lass mich wissen wie es gelaufen ist

Mein Build-Skript macht ein bisschen mehr Dinge, aber es sieht so aus, als ob es wie ein Zauber funktioniert:

"build": "graphql codegen && next build && npm run export",

Außerdem ist es großartig! Es war genau das, was ich gesucht habe 😅 (Auf Wiedersehen GatsbyJS, mein Lieblingsframework ist jetzt so stark wie du!)

Vielen Dank für diese Reaktivität.

Ich habe auch ein Upgrade auf 9.1.6 und das habe ich überraschenderweise gesehen
Screenshot 2019-12-21 at 19 25 43

Ich dachte, dieser Thread wäre ein RFC, es sieht so aus, als wäre er bereits für uns geöffnet, nicht wahr?
Typoskript-Typen sind jedoch in 9.1.6 nicht aktiviert.

Verdammt, darauf bin ich jetzt so gehyped! 🤣

Letzte Fragen:

  • Wenn ich es bekomme, wird getInitialProps in Zukunft eingestellt? Oder ist es in manchen Fällen noch relevant? Ein Beispiel?
  • next export kann auch zugunsten von Seiten mit getStaticProps und nur next build ?

Danke für das tolle Tool 🙏🏻

Wenn ich es erhalte, wird getInitialProps in Zukunft veraltet sein? Oder ist es in manchen Fällen noch relevant? Ein Beispiel?

Wie im ersten RFC gesagt:

Dieser RFC behandelt ausschließlich API-Ergänzungen. Alle neuen Funktionen sind vollständig abwärtskompatibel und können schrittweise übernommen werden. Dieser RFC führt keine veralteten Versionen ein.

Ich dachte, dieser Thread wäre ein RFC, es sieht so aus, als wäre er bereits für uns geöffnet, nicht wahr?

Ist es nicht, wir probieren es auf ZEIT-Anwendungen aus und einige Sichtbarkeitsflächen sind bereits gelandet (z. B. der Seitenbaum, den Sie gesehen haben).

next export kann auch zugunsten von Seiten mit getStaticProps und next build nur veraltet sein?

Richtig, im Allgemeinen werden Sie next export einfach nicht verwenden. Es wird aus Gründen der Rückwärtskompatibilität beibehalten, aber im Allgemeinen sollten Sie eine Hybrid-App erstellen, da Sie alle Vorteile des Exports mit Unterstützung für andere Funktionen wie API-Routen und die Option für serverseitiges Rendering für einige Seiten erhalten.

Wie können wir diese ausprobieren?

Ich denke, alle diese Methoden benötigen derzeit das Präfix unstable_ , um erkannt zu werden.

zB unstable_getStaticProps

Es wird dringend empfohlen, es noch nicht zu verwenden, es ist experimentell und kann zwischen den Veröffentlichungen unterbrochen werden.

Ich habe also mit dieser Funktion gespielt und festgestellt, dass die JSON-Datei mit den Seitendaten immer nach dem Zugriff auf die SSG-Seite von einer anderen Seite abgerufen wird.

Planen Sie eine Optimierung des Preloads für die JSON-Datei?
Vielleicht laden Sie es vorab, wenn der Benutzer zu der Seite navigieren möchte (dh: der Benutzer bewegt sich über einen SSG-Link) oder das Vorladen, genau wie Sie andere js-Seiten vorab laden, die von einer Link-Komponente referenziert werden.

Ich liebe diese Funktion übrigens!

Planen Sie eine Optimierung des Preloads für die JSON-Datei?

Jawohl.

Für das, was es wert ist, bin ich eher für baumschüttelbare Exporte dieser Funktionen als für separate Dateien.

Wie ist der Status dieser Funktion? Was sind seine Blocker?

@mikestop setzt fort, dass dieser RFC derzeit intern von unserem Team und einigen ausgewählten Partnern intensiv getestet wird. Sie können sich für das sehr experimentelle Verhalten entscheiden, indem Sie die Präfixe unstable_ , wie oben erwähnt ! 😄

Bitte migrieren Sie jedoch keine Produktionsworkloads auf die neuen Methoden, da wir die APIs möglicherweise immer noch auf bahnbrechende Weise aktualisieren.

Persönlich verwende ich es für die Generierung von statischen Sites von 8 bis 20K Seiten (mit der Möglichkeit, einige dynamische Anfragen auf einigen Seiten zu haben). Es funktioniert sehr gut (mit Ausnahme des 10K-Dateienlimits bei Now), das einzige, was ich schade finde, ist, dass ohne die Methode getStaticPaths getStaticProps bei jedem Neuladen aufgerufen wird. Ein Verhalten, das gut sein könnte, ist, dass der erste Aufruf die JSON-Datei erstellt und der nächste verwendet sie.

Sind inkrementelle Builds geplant? Also werden nur neue/geänderte Inhalte neu erstellt?

Sie können sich für das sehr experimentelle Verhalten entscheiden, indem Sie die Präfixe unstable_ , wie oben erwähnt !

Ich möchte die Methode unstable_getServerProps testen, aber es sieht so aus, als ob sie im Moment ignoriert wird und ich sie nirgendwo im zeit/next.js Repository finden kann. Ist es noch nicht implementiert oder mache ich es nur falsch?

Sind inkrementelle Builds geplant? Also werden nur neue/geänderte Inhalte neu erstellt?

Die Implementierung wurde im Hinblick auf inkrementelle Neuerstellungen entwickelt, wird jedoch noch nicht unterstützt (und in diesem RFC auch nicht behandelt).

Seien Sie versichert, die Architektur ist fertig und wir werden dies untersuchen, nachdem diese Funktionen stabil sind.
Aus diesem Grund wird getStaticProps pro Seite definiert und nicht einmal für die gesamte Anwendung!

Ich würde gerne die Methode unstable_getServerProps testen, aber es sieht so aus, als ob sie im Moment ignoriert [...]

getServerProps ist noch nicht in der Vorschau verfügbar, tut mir leid!

getServerProps ist noch nicht in der Vorschau verfügbar, tut mir leid!

Danke für die Warnung. Ich werde mir diesen Thread auf jeden Fall ansehen, denn wenn er landet, habe ich eine Menge Code, der durch Umbenennen einer einzelnen Funktion ersetzt werden kann! 😍

Bitte klären Sie, ich bin mir nicht 100% sicher, ob getServerProps / getStaticProps derzeit verfügbar sind oder nicht.

Basierend auf diesem Thread: Nein

Aber wenn das der Fall ist, frage ich mich, warum mein Terminal darauf angespielt hat, als ich next build wenn sie noch nicht verfügbar sind? Als ich die Nachricht sah, hatte ich zunächst die Annahme, dass diese Methoden in Produktion waren, und es dauerte eine Weile, bis ich entdeckte, dass dies nicht der Fall war. Ich bin nur neugierig auf die Begründung oder ob ich etwas falsch verstehe.

λ  (Server)  server-side renders at runtime (uses getInitialProps or getServerProps)
○  (Static)  automatically rendered as static HTML (uses no initial props)
●  (SSG)     automatically generated as static HTML + JSON (uses getStaticProps)

(auf nächster Version 9.1.6)

Vielen Dank

@stevenjchang Sie sind mit der folgenden Syntax in pages/**/*.js verfügbar:

export function unstable_getStaticPaths() {} // return [{params: {...}}, ...]
export function unstable_getStaticProps({params: {...}) {} // return {props: {...}}

Und ich sollte auch hinzufügen, dass sie wunderbar sind, obwohl sie bei der Verwendung des Dev-Servers immer noch etwas rau sind.

obwohl sie bei der Verwendung des Dev-Servers immer noch etwas rau sind.
@mikestop macht weiter

Könnten Sie das bitte näher ausführen? Niemand sonst hat uns negatives Feedback über die Erfahrung mit dem Entwicklerserver gegeben, und wir würden es gerne lösen!

@Timer Ich mag die neue API sehr. Mein Hauptproblem während der Entwicklung ist, dass der Json bei jedem Ladevorgang erneut angefordert wird. Dies verlangsamt das Testen, stellt aber auch die Erfahrung des Benutzers beim Surfen auf der Website falsch dar.

Meinst du mit "bei jedem Ladevorgang" Seitenladevorgänge? Oder umbauen? Oder...?

@mmmeff Jedes Mal, wenn Sie zu demselben Pfad navigieren, wird die json erneut angefordert. Wenn Sie also zwischen zwei Seiten hin- und herklicken, verbringen Sie viel Zeit damit, auf Daten zu warten.

@mikestop fährt fort, dies ist das beabsichtigte Verhalten, da die aktuellsten Daten in der Entwicklung oft vorzuziehen sind. Wäre offen für eine Diskussion über bessere Heuristiken in einer neuen Ausgabe!

@timneutkens Dieser RFC sieht sehr vielversprechend aus. Ich habe ein paar Fragen/Bedenken zum Thema Sicherheit und wie es genau funktioniert.

Nehmen wir einen generischen Business Case, der sowohl auf SSR als auch auf SSG beruht.

Kontext

Wir möchten einige Informationen auf einer Website (AKA "App") anzeigen.
Diese Informationen werden in einem BDD gespeichert, auf das über eine GraphQL-API zugegriffen werden kann.
Einige dieser Informationen sind öffentlich, andere privat (zB: Benutzer-E-Mails/Passwort).

Die App verwendet zwei Stufen:

  • Eine „Staging“-Phase, in der der Kunde Änderungen in Echtzeit in der Staging-App sehen kann (er aktualisiert diese Informationen über ein Back-Office oder ähnliches).
  • Eine „Produktionsstufe“, auf die der Kunde keinen Zugriff hat und nichts selbst aktualisieren kann. Um die Produktions-App zu aktualisieren, muss eine neue Bereitstellung erfolgen. (Sie bitten um eine neue Produktionsbereitstellung von ihrem Back-Office aus)

In diesem Szenario verwenden wir sowohl SSR als auch SSG:

  • Die Staging-App verwendet SSR, da sie die Daten in Echtzeit von der GraphQL-API abruft (beim Erstellen einer Seite).
  • Die Produktions-App verwendet SSG, da sie bei einer neuen Bereitstellung die Daten von der GraphQL-API abruft und daraus statische Seiten generiert (sie sind daher statisch und ändern sich nicht mehr, es wird keine Abfrage an die GraphQL-API gestellt zur Laufzeit (zumindest nicht beim Laden einer Seite))

Dieses Szenario sollte generisch genug sein und (IMHO) einer der Hauptanwendungsfälle der SSG-Nutzung sein.
Die Produktions-App ist nichts anderes als eine Momentaufnahme der Staging-App.

Ein paar Fragen:

  1. Ist das mit diesem RFC möglich ? Dass sich dieselbe App basierend auf einer bestimmten "Phase" (Produktion/Inszenierung) unterschiedlich verhält
  2. Wie werden die Daten aus der GraphQL-API injiziert?

    • Beim Staging werden sie dynamisch über SSR oder CSR abgerufen, während der Benutzer durch die Seiten navigiert (und sind im Browser verfügbar, wenn sie während der CSR abgerufen werden).

    • In der Produktion werden sie zur Build-Zeit abgerufen, aber werden sie dann in einer globalen JS-Variablen gespeichert und können somit von jedem gelesen werden? (Sicherheitsbedenken, da wir uns bewusst sein müssen, keine sensiblen Daten abzurufen, die möglicherweise im Browser verfügbar sind, ähnlich wie bei der Verwendung von CSR)

  3. Hätten Sie Bedenken bezüglich dieses Ansatzes mit gemischter SSR/SSG? (Sicherheit, Leistung, Wartbarkeit usw.)

Wann planen Sie die Veröffentlichung? Wird es ein großes Update (v10) oder ein abwärtskompatibles Update sein?

Hey,

Haben Sie diese Lösung mit einem benutzerdefinierten Server ausprobiert und zum Laufen gebracht?

Beispiel:

// server.js

const express = require('express');
const next = require('next');

const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();

app.prepare().then(() => {
  const server = express();

  server.get('/blog/:id', (req, res) => {
    console.log('My params needed be passed to page:', req.params);
    return app.render(req, res, '/blogDetail', { id: req.params.id });
  });

  server.listen(port, err => {
    if (err) throw err;
    console.log(`> Ready on http://localhost:${port}`);
  });
});

// blogDetail.js
export async function unstable_getStaticProps(props) {
  console.log('What is passed', props);

  return {};
}

const BlogPostPage = ({ post }) => {
  return <div>Hey</div>;
}

export default BlogPostPage;
# Terminal output

My params needed be passed to page: { id: 'test' }
What is passed { params: undefined }

Warum kann getStaticProps die Abfragezeichenfolge nicht einschließen? Ich habe derzeit eine Seite, auf der ich einfach SSR verwenden muss, um die Abfrageparameter ohne erneutes Rendern zu erhalten. Die Verwendung des useRouter Hooks führt zu mehreren Re-Renderings, da query anfänglich ein leeres Objekt ist. Dies ist eine Seite, die für das Conversion-Tracking verwendet wird, also ist das offensichtlich kein Starter.

@pjaws Der RFC erwähnt ausdrücklich, dass getStaticProps für die statische Generierung bestimmt ist. Statisches HTML kann keine Abfragezeichenfolge empfangen.

Warum kann es dann dynamische URL-Parameter empfangen? Wie ist das anders?

Am Di, 14. Januar 2020 um 01:30 Uhr Tim Neutkens [email protected]
schrieb:

@pjaws https://github.com/pjaws Der RFC, der ausdrücklich erwähnt wird
getStaticProps ist für die statische Generierung. Statisches HTML kann kein a . empfangen
Abfragezeichenfolge.


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/zeit/next.js/issues/9524?email_source=notifications&email_token=AMVRRIQCKDJNF4MPWSLYNV3Q5WA2NA5CNFSM4JRPBEL2YY3PNVWWK3TUL52HS4DFVREXG43VMVBWLOW63LNMVXHJKT
oder abmelden
https://github.com/notifications/unsubscribe-auth/AMVRRIRJXLYC4MC4U7DH7NDQ5WA2NANCNFSM4JRPBELQ
.

Denn in getStaticPaths Sie die Seiten zurückgeben, die zur Build-Zeit gerendert werden.

Diese Änderungen sehen sehr vielversprechend aus, tolle Arbeit wie immer! 👍

Ich frage mich über den Anwendungsfall von getInitialProps in _app.js , um Datenanforderungen zu erfüllen, die über die Seiten hinweg geteilt werden (zB Einrichten von Kontextanbietern). Verstehe ich richtig, dass es unmöglich ist, getStaticProps auf die gleiche Weise zu verwenden? Kann man es nur in einzelnen Seiten definieren?

Ich frage mich über den Anwendungsfall von getInitialProps in _app.js, um Datenanforderungen zu erfüllen, die über die Seiten hinweg geteilt werden (z. B. Einrichten von Kontextanbietern). Verstehe ich richtig, dass es unmöglich ist, getStaticProps auf die gleiche Weise zu verwenden? Kann man es nur in einzelnen Seiten definieren?

Richtig, zunächst nur für einzelne Seiten. Kann es später noch einmal überdenken. Die getInitialProps von _app werden beim Exportieren in statisches HTML weiterhin aufgerufen, sodass Sie inkrementell zu getStaticProps wechseln können.

Hallo Leute, eine verwandte Frage - wie werden Vermögenswerte behandelt? weil ich gerade sehe, dass, wenn ich ein Headless-CMS (sogar WordPress oder Graphcms oder was auch immer) verwende, die Asset-URL im statischen HTML verwendet wird.

Hier gibt es zwei Präferenzen - dass Asset-Links als solche verwendet werden.
Aber wahrscheinlicher - laden Sie das Asset herunter, erstellen Sie den HTML-Code (lokal verlinken) und legen Sie dann ein CDN vor. Dies ist die weitaus akzeptablere Praxis.

Dies passt auch sehr gut zum Einsatz von Deployment-Systemen wie Netlify – die über eine weitaus geeignetere global verfügbare Infrastruktur verfügen als etwa DatoCMS oder Graphcms. Wenn ich also Netlify als Bereitstellung verwende, möchte ich, dass alles von der Netlify-Domäne bereitgestellt wird und es seine Magie wirken lässt.

@sandys Wenn ich in https://github.com/zeit/next.js/issues/9054#issuecomment -570427085 richtig verstanden habe, solltest du die Assets herunterladen, unter .next/static speichern und einen Link erstellen selbst in getStaticProps .

Es gibt auch die Idee, statische API-Routen zu verwenden, aber ich bin mir nicht sicher, wie Sie das Browser-Caching-Verhalten damit steuern würden.

@Janpot danke für die Verlinkung. Die Kommentare dort scheinen darauf hinzudeuten, dass dieses Zeug selbst gerollt werden muss.

Bitte fügen Sie meine Anfrage hinzu, dies integriert zu haben. Vielleicht ist #9054 allgemeiner, aber ich denke aus der Perspektive von SSG und das ist EXTREM wichtig.

Ich habe vergessen zu erwähnen, aber auch Asset-Hashing wird für SSG unerlässlich sein.

@homoky , Laufen bringen, hast du in der Zwischenzeit Fortschritte gemacht?

@homoky , Laufen bringen, hast du in der Zwischenzeit Fortschritte gemacht?

Es ist nicht möglich und auch nicht geplant: #10071

😢

@sandys eigentlich ist die Lösung viel einfacher, wenn Sie https://github.com/zeit/next.js/issues/9081 verwenden , um ein Rewrite von zB /images zum CMS hinzuzufügen. ZB auf ZEIT Jetzt würde es das Ergebnis bereits zwischenspeichern, wenn die richtigen Header hinzugefügt werden, kein zusätzliches Herunterladen erforderlich (massiver Overhead beim Build).

@timneutkens danke für die Antwort.
Nicht ganz sicher, was du meinst. Wir verwenden also netlify - schlagen Sie vor, dass wir die CMS-URLs als solche beibehalten und eine CDN-Schicht darüber legen?
Ich bin mir nicht ganz sicher, ob Netlify (Cloudfront, das wir verwenden wollen) mit all diesen Diensten reibungslos funktionieren kann.

Wenn die Images heruntergeladen und Teil der Bereitstellung werden, wird dieses ganze Problem massiv vereinfacht. Weil ich CDN so eingerichtet habe, dass es von der Basis-URL zwischengespeichert wird (die in meinem Fall von s3 bedient wird).

Ich bin mir nicht ganz sicher, ob Ihre Lösung davon abhängt, dass ich Zeit NOW verwende

Wenn die Images heruntergeladen und Teil der Bereitstellung werden, wird dieses ganze Problem massiv vereinfacht. Weil ich CDN so eingerichtet habe, dass es von der Basis-URL zwischengespeichert wird (die in meinem Fall von s3 bedient wird).

Dies macht den Build-Prozess tatsächlich viel komplexer und 10x langsamer, definitiv nicht einfacher.

Ich bin mir nicht ganz sicher, ob Ihre Lösung davon abhängt, dass ich Zeit NOW verwende

Funktioniert mit jedem Proxy der Welt. Inklusive Cloudfront.

@timneutkens Wir sind der Build-Prozesszeit eigentlich agnostisch. egal ob es länger dauert. aber aus vielen Gründen (einschließlich aller Assets, die von einer bekannten Basis-URL bereitgestellt werden), wäre es sehr vorzuziehen, diese im Build zu speichern.

Ich befürworte sicherlich nicht, dass Sie dies für alle aktivieren. Viele Leute werden gerne Deeplinks zu einem CMS erstellen. Aber wir betreiben eine Website mit hohem Traffic und das ist definitiv etwas, was Websites wie wir brauchen.

Verzeihen Sie mir auch, aber ich habe Ihre Lösung nicht verstanden. wie sollen wir das konfigurieren? Ich habe keine Kontrolle darüber, welche URL ein CMS verwendet. Zum Beispiel beginnt Datocms mit der Bereitstellung von www.datocms-assets.com/ . Wie verwenden wir die Lösung in #9081 ?

Wir sind der Build-Prozesszeit eigentlich agnostisch. egal ob es länger dauert

Dies mag für Ihre Anwendung zutreffen, für die meisten Anwendungen ist dies jedoch nicht der Fall.

aber aus vielen Gründen (einschließlich aller Assets, die von einer bekannten Basis-URL bereitgestellt werden), wäre es sehr vorzuziehen, diese im Build zu speichern.

Es muss wirklich nicht so sein, wie gesagt, Sie können ein Rewrite verwenden, das /images/* an die cms-URL weiterleitet, zum Beispiel www.datocms-asset.com/* oder ähnliches. Und dann verlinken Sie einfach alle Bilder mit /images .

Beachten Sie, dass dies allmählich vom Thema abweicht.

@sandys eigentlich ist die Lösung viel einfacher, wenn Sie #9081 verwenden, um ein Rewrite von zB /images zum CMS hinzuzufügen. ZB auf ZEIT Jetzt würde es das Ergebnis bereits zwischenspeichern, wenn die richtigen Header hinzugefügt werden, kein zusätzliches Herunterladen erforderlich (massiver Overhead beim Build).

@timneutkens Nur um die Dinge für mich klar zu machen. Im Idealfall würden Sie das Bild hashen und für immer im Browser unter einer eindeutigen URL zwischenspeichern, und Inhaltsersteller können die Datei jederzeit unter demselben Namen im CMS aktualisieren. Das bedeutet also, dass das CMS in dem von Ihnen vorgeschlagenen Setup verantwortlich sein müsste für:

  1. Optimierung der Bilder
  2. Hashing der Bilder und Bereitstellung unter diesem Hash
  3. Stellen Sie eine Karte von der Bild-URL zur gehashten Bild-URL bereit, die in getStaticProps heruntergeladen werden kann, um die Bild-URLs ihrem unveränderlichen Gegenstück auf dem CMS neu zuzuordnen

Was, denke ich, nicht unmöglich ist. Ich möchte nur sicherstellen, dass dies das vorgeschlagene Setup ist.

@Janpot CMS-Anbieter handhaben dies bereits, indem sie eine eindeutige URL für Bilder usw.

@sandys dies hat nichts mit dem SSG RFC zu tun, also

Wollte jedoch nur erwähnen, dass dies in all unseren Köpfen eng mit SSG verbunden ist. Da dies der Idealfall für den SSG-Exportbefehl ist. Dies ist in anderen Fällen im Allgemeinen nicht erforderlich.
Im besten Fall ist dies eine optionale Funktion beim nächsten Export.

Aber wie Sie wollen - respektieren Sie Ihre Entscheidung.

Aber es ist etwas, das next export derzeit nicht einmal tut. Daher ist es eine völlig neue Sache und hat nichts mit diesem RFC zu tun.

Das geht auch nicht mit getServerProps und On-Demand-Rendering.

@Janpot CMS-Anbieter handhaben dies bereits, indem sie eine eindeutige URL für Bilder usw.

👍 ja, das macht Sinn. Das bedeutet aber auch, dass Sie zwei Möglichkeiten haben, wenn Sie Bilder in Ihrem Projekt verwenden und diese optimieren und zwischenspeichern möchten:

  1. Erstellen Sie ein benutzerdefiniertes Webpack-Setup
  2. ein externes CMS verwenden

bearbeiten:

Und wenn ich richtig verstehe, file-loader ist bereits für CSS enthalten. Geht es nicht auch darum, es für JS zu aktivieren?

@Janpot Der von Sandeep erwähnte spezifische Punkt ist, dass die URLs von einer externen Quelle stammen würden, nicht vom Projekt selbst. Das standardmäßige Einschließen des Dateiladers ist eine andere Funktionsanforderung.

Mir ist aufgefallen, dass für Seiten, die für ZEIT Now bereitgestellt werden, wenn ich eine Seite mit einer dynamischen URL habe, die die neuen statischen APIs verwendet, für Seiten, die nicht statisch mit unstable_getStaticPaths generiert wurden, die Funktion unstable_getStaticProps zur Laufzeit auf dem Server ausgeführt, anstatt 404 zurückzugeben.

ZB habe ich eine Seite /blog/[slug].js , deren getStaticPaths das Array zurückgibt:

[{ params: { slug: 'hello' } }]

und mein getStaticProps hat eine Logik, um eine Datei basierend auf dem Slug zu lesen. Wenn ich /blog/hello besuche, wird die Seite wie erwartet vorgerendert, aber wenn ich eine ungültige Seite wie /blog/doesnt-exist besuche, dann wird getStaticProps zur Laufzeit ausgeführt und ich erhalte einen Fehler 500, anstatt a 404. Oder wenn ich eine Fehlerbehandlung hinzufüge, wird die Seite anstelle eines 404 gerendert, obwohl sie nicht in der Ausgabe von getStaticPaths .

Ist diese Logik beabsichtigt?

Dies ist eine große Verbesserung. Wir waren gerade dabei, einige vorgefertigte Skripte zu schreiben, um genau dies zu tun.
Ich habe gerade getestet, eine unserer Sites auf Next 9.2 auf unstable_getStaticPaths und unstable_getStaticProps zu verschieben, und es hat gut funktioniert.

Wir haben eine Regression im Vergleich zu exportPathMap : Wenn Sie einen Pfad mit exportPathMap erstellen, können Sie Folgendes angeben:

{
 "/path/to/page": {page: "/index", query: { pageId: 123 } }
}

und der statische Build wird aufgebaut

/path
   /to
     /page
       index.html

Wenn Sie das Äquivalent von unstable_getStaticPaths in der Vorlage [slug].jsx ,

[{ slug: '/path/to/page' }]

Next 9.2 generiert '%2Fpath%2Fto%2Fpage' anstelle der verschachtelten Verzeichnisse.

/%2Fpath%2Fto%2F
   index.html

Der Aufbau von Verzeichnissen (die dem bestehenden exportPathMap-Verhalten entsprechen) ist wichtig für den Aufbau von Seiten. Wir verwenden eine einzelne Vorlagendatei, aber der veröffentlichte Pfad kann beliebig verschachtelt sein.

@dpfavand in diesem Fall sollten Sie eine Catch-All-Route verwenden: https://nextjs.org/blog/next-9-2#catch -all-dynamic-routes

Möglicherweise können wir warnen, wenn Sie versuchen, einen Pfad mit Schrägstrichen zurückzugeben, aber das Verhalten ist korrekt, wenn Sie [slug].js , in Ihrem Fall möchten Sie [...slug].js .

Wann soll dieser landen? Wird es ein Patch von 9.2 oder eine eigene Nebenversion sein?

Wir wissen die ganze Aufregung rund um dieses Feature wirklich zu schätzen. Wie an anderer Stelle erwähnt, teilen wir im Allgemeinen keine Zeitpläne für Funktionen, da wir sicherstellen möchten, dass sie die richtige Entwicklererfahrung, Einschränkungen und Zukunftssicherheit aufweisen.

Da es sich um ein neues Feature handelt, wird es nur geringfügig sein.

Ja, das würde ich normalerweise verstehen, aber der 9.1.7-Blog hat den Eindruck erweckt
es war schon in freier Wildbahn.

Am Fr, 17. Januar 2020 um 17:05 Uhr Tim Neutkens [email protected]
schrieb:

Wir wissen die ganze Aufregung rund um dieses Feature wirklich zu schätzen. Wie erwähnt
andernorts teilen wir im Allgemeinen keine Zeitleisten für Funktionen, wie wir es möchten
Stellen Sie sicher, dass sie die richtige Entwicklererfahrung, Einschränkungen und Zukunft haben
Beweiskraft.


Sie erhalten dies, weil Sie einen Kommentar abgegeben haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/zeit/next.js/issues/9524?email_source=notifications&email_token=ADKINGF724256WCEFHBFIH3Q6ITRXA5CNFSM4JRPBEL2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKT-DN5WWZ
oder abmelden
https://github.com/notifications/unsubscribe-auth/ADKINGBVCG6MFMOG5U2FGMDQ6ITRXANCNFSM4JRPBELQ
.

>

Lassiter Gregg
[email protected] [email protected]
Zelle (832) 495-9903

Gibt es so etwas wie getStaticProps aber nur einmal für die gesamte App statt pro Seite ausgeführt wird?

Mein Anwendungsfall ist, dass ich einen React Context ( PricingPlansContext ) habe, der von mehreren Seiten verwendet wird und ich möchte, dass die Daten (Preispläne) nur einmal von meinem externen Server zur Build-Zeit abgerufen werden ( next export ). Nie zur Laufzeit und ohne die getStaticProps von jeder Seite hinzufügen zu müssen.

BEARBEITEN: Oben einen entsprechenden Kommentar gefunden: https://github.com/zeit/next.js/issues/9524#issuecomment -574179540. Hoffentlich wird es berücksichtigt.

Ich benutze dafür babel plugin-preval`, obwohl ich auch gesehen habe, wie Leute a
json-Datei innerhalb von exportPathMa() mit next.config.js, die sie dann importieren
innerhalb ihres Codes.

Am Ende habe ich eine Json-Datei mit einem npm-Skript geschrieben, aber danke für den Vorschlag von exportPathMap, vielleicht ist das ein besserer Ort.

@dpfavand in diesem Fall sollten Sie eine Catch-All-Route verwenden: https://nextjs.org/blog/next-9-2#catch -all-dynamic-routes

Möglicherweise können wir warnen, wenn Sie versuchen, einen Pfad mit Schrägstrichen zurückzugeben, aber das Verhalten ist korrekt, wenn Sie [slug].js , in Ihrem Fall möchten Sie [...slug].js .

@timneutkens danke für das Follow-up. Ich habe zwei Methoden ohne Erfolg ausprobiert. Wenn der Slug-Wert als String in getStaticPaths , wird er grundsätzlich nicht an getStaticProps . Wenn der Slug-Wert als Array zurückgegeben wird, schlägt der Build fehl, da der Wert ein String sein muss.

Fall 1, Angenommen eine Datei pages/[...slug].jsx , Slug als String:

export async function unstable_getStaticPaths() {
    return [{ params: { slug: 'en/about' } }];
}

export async function unstable_getStaticProps({ params }) {
    console.log('params', params);
    return { slug: params.slug };
}

Im obigen Fall ist params in getStaticProps ein leeres Objekt - kein slug Schlüssel.

Fall 2, pages/[...slug].jsx , Slug als Array,

export async function unstable_getStaticPaths() {
    const allPaths = Object.keys(pathMap).map(slug => ({ params: { slug } }));
    return [{ params: { slug: ['en', 'about'] } }];
}
export async function unstable_getStaticProps({ params }) {
    console.log('params', params);
    return { slug: params.slug };
}

In Fall 2 schlägt der Build fehl mit

> Build error occurred
{ Error: A required parameter (slug) was not provided as a string.
    at _validParamKeys.forEach.validParamKey (/project/node_modules/next/dist/build/utils.js:21:569)
    at Array.forEach (<anonymous>)
    at toPrerender.forEach.entry (/project/node_modules/next/dist/build/utils.js:21:495)
    at Array.forEach (<anonymous>)
    at Object.isPageStatic (/project/node_modules/next/dist/build/utils.js:17:122)
    at process._tickCallback (internal/process/next_tick.js:68:7) type: 'Error' }

Ich sehe nur Pfadparameter in den obigen Beispielen für getStaticPaths . Wird es möglich sein, SSG-Pfade zu erstellen, die Abfrageparameter enthalten? Zum Beispiel:

/store/widgets/circles-n-squares?sort=price&minWeight=2&color=black

Ich denke insbesondere aus der Perspektive einer E-Commerce-Site, bei der es schwierig wäre, jede einzelne Facette der Produktsuche in den pathname einer URL abzudecken.

Ich habe hier vor kurzem eine Nachricht gepostet und keine Antwort erhalten - im Wesentlichen verhält sich getStaticProps wie getServerProps wenn eine Site an ZEIT Now bereitgestellt wird (dh getStaticPaths ignoriert und Anfragen bearbeitet) dynamisch) - Ich denke, das ist ein Fehler?

@dpfavand genau das Starter-Site für Agilitycms und nextjs mit dynamischem

@timneutkens danke für das Follow-up. Ich habe zwei Methoden ohne Erfolg ausprobiert. Wenn der Slug-Wert als String in getStaticPaths , wird er grundsätzlich nicht an getStaticProps .

Fall 1, Angenommen eine Datei pages/[...slug].jsx , Slug als String:

export async function unstable_getStaticPaths() {
  return [{ params: { slug: 'en/about' } }];
}

export async function unstable_getStaticProps({ params }) {
  console.log('params', params);
  return { slug: params.slug };
}

Im obigen Fall ist params in getStaticProps ein leeres Objekt - kein slug Schlüssel.

Übrigens, kleine Welt! Nochmals vielen Dank, dass Sie bei fastr_conf gesprochen haben.

Hallo @timneutkens ,

Ich bin sehr begeistert von der Idee, dass sich next.js wie ein statischer Site-Generator verhält.

Ich möchte fragen, wie die Methoden getStaticProps und getStaticPaths werden können, wenn ein großer Datenblock einmal angefordert und dann zum Generieren verschiedener Seiten verwendet wird.

Ich verwende beispielsweise einen JavaScript-SDK-Client eines API-basierten CMS, der über eine Methode zum Abrufen aller verfügbaren Objekte verfügt. Einige dieser Objekte repräsentieren Site-Seiten.

const entries = await cmsSdkCient.getEntries();

Bisher habe ich die Methode exportPathMap verwendet, um alle Einträge aus dem CMS auf einmal abzurufen und eine Karte zwischen den Pfaden dieser Seite und ihren Daten zu erstellen. Die Funktion exportPathMap macht zwei Dinge:

  1. Stellt eine Seitenkarte mit ihren Daten und ssr: true , die von getInitialProps zum Zeitpunkt des Exports verbraucht werden
  2. Schreibt dieselben Daten, diesmal mit ssr: false , in init-props.json Dateien, die in dem Ordner abgelegt werden, der dem Pfad jeder Seite entspricht. Wenn dann getInitialProps vom Client aufgerufen wird, werden die benötigten Daten von init-props.json der übereinstimmenden Seite geladen.


next.config.js mit exportPathMap

module.exports = {
  exportTrailingSlash: true,
  exportPathMap: (defaultPathMap, { outDir }) => {
    // load data from CMS
    const objects = await cmsSdkCient.getEntries();

    // create map between page paths and page data
    return objects.reduce((accum, object) => {

      // if the object does not have a slug, it is not a page
      if (!object.slug) return accum;

      const pagePath = '/' + object.slug;
      const ssrQueryData = Object.assign({ ssr: true }, object);
      const clientQueryData = Object.assign({ ssr: false }, object);

      // generate the map for export phase with {ssr: true}
      accum[pagePath] = {
        // using additional fields from the page object,
        // the pageFromPagePath() computes which page file should
        // be used to render the page object
        page: pageFromPagePath(object),
        query: ssrQueryData
      };

      // write json files that will be loaded by client
      if (outDir) {
        const jsonFilePath = path.join(outDir, _.trim(pagePath, '/'), 'init-props.json');
        fse.outputFileSync(jsonFilePath, JSON.stringify(clientQueryData));
      }

      return accum;
    }, {});
  }
}


Seiten/my_page.js mit getInitialProps

Index.getInitialProps = async (context) => {
  const ssr = _.get(context, 'query.ssr', false);
  if (ssr) {
    // we are on server, return the data
    return _.get(context, 'query', {});
  } else {
    // we are on client side, request the data through /init-props.json endpoint
    const url = context.asPath + '/init-props.json';
    return fetch(url).then(response => {
      return response.json();
    });
  }
};

Ich kann den großen Vorteil der Verwendung der Methoden getStaticProps und getStaticPaths , die einen Großteil meines Codes im Zusammenhang mit dem Speichern von JSON-Dateien und dem Laden vom Client reduzieren.

// pages/my_page.js
export async function getStaticProps(context) {
  const objects = await cmsSdkCient.getEntries();
  const props = _.find(object, { type: 'my_page' })
  return { props };
}

// pages/blog/[slug].js
export async function getStaticProps(context) {
  const objects = await cmsSdkCient.getEntries();
  const props = _.find(object, { type: 'post', slug: context.params.slug })
  return { props };
}

export async function getStaticPaths() {
  const objects = await cmsSdkCient.getEntries();
  return objects
    .filter(object => object.type === 'post')
    .map(object => ({ params: { slug: object.slug } }))
}

Was mich beschäftigt, ist die Frage, wie ich den Workflow optimieren kann, um alle Einträge einmal zu bringen, anstatt sie jedes Mal abzurufen, wenn getStaticProps oder getStaticPaths aufgerufen werden?

Eine andere Frage hat möglicherweise nicht unbedingt mit diesem Problem zu tun, aber da wir uns in der Welt der SSGs und Remote-Datenquellen befinden, lohnt es sich, sie zu stellen. Angenommen, next.js läuft im Dev-Modus, wie kann man next.js benachrichtigen, diese Methoden erneut auszuführen, um die Remote-Daten erneut abzurufen und die Site neu aufzubauen.

@smnh Da es sich um „nur JavaScript“ handelt, können Sie Ihre Einträge einmal

Was Ihre zweite Frage betrifft, geschieht dies automatisch. Führen Sie next dev und Sie können loslegen.

Ich sehe nur Pfadparameter in den obigen Beispielen für getStaticPaths . Wird es möglich sein, SSG-Pfade zu erstellen, die Abfrageparameter enthalten? Zum Beispiel:

/store/widgets/circles-n-squares?sort=price&minWeight=2&color=black

Ich denke insbesondere aus der Perspektive einer E-Commerce-Site, bei der es schwierig wäre, jede einzelne Facette der Produktsuche in den pathname einer URL abzudecken.

Ich glaube nicht, dass dies im Kontext von ssg sinnvoll ist. SSG gibt für jeden Eintrag eine Datei aus - Abfrageparameter sind nicht Teil des Dateinamens, daher benötigen Sie eine Serverschicht, um die Anforderungen in eine tatsächliche Datei umzuschreiben. (Wie wäre Ihr statischer Dateiname im obigen Beispiel?) Ich würde vorschlagen, die Standardansicht (die Sie erhalten, wenn Sie die Seite ohne Facetten besuchen) vorab zu rendern und auf der Clientseite zu aktualisieren, wenn Abfrageparameter für die Anfrage vorhanden sind. Aber das wird ein Thema jenseits dieses SSG RFC.

@dpfavand genau das Starter-Site für Agilitycms und nextjs mit dynamischem

@timneutkens danke für das Follow-up. Ich habe zwei Methoden ohne Erfolg ausprobiert. Wenn der Slug-Wert als String in getStaticPaths , wird er grundsätzlich nicht an getStaticProps .
Fall 1, Angenommen eine Datei pages/[...slug].jsx , Slug als String:

export async function unstable_getStaticPaths() {
    return [{ params: { slug: 'en/about' } }];
}

export async function unstable_getStaticProps({ params }) {
    console.log('params', params);
    return { slug: params.slug };
}

Im obigen Fall ist params in getStaticProps ein leeres Objekt - kein slug Schlüssel.

Übrigens, kleine Welt! Nochmals vielen Dank, dass Sie bei fastr_conf gesprochen haben.

Hey! Das Nextjs-Team hat damit begonnen, sich damit zu befassen, es ist ein Ticket offen, um einige zusätzliche Probleme mit der aktuellen Canary-Implementierung zu lösen: https://github.com/zeit/next.js/issues/10190

@smnh Am Ende habe ich ein Skript, das den freigegebenen Inhalt vorab

Für Rebuilds habe ich Webhooks im CMS eingerichtet, um Netlify-Build-Hooks auszulösen, wenn sich relevante Inhalte ändern. GetStaticProps kann dann einfach seitenspezifischen Inhalt abrufen.

Danke @zeusdeux
Betreff:

Was Ihre zweite Frage betrifft, geschieht dies automatisch. Führen Sie den nächsten Entwickler aus und Sie können loslegen.

Wenn ich sie in einem Modul zwischenspeichere und dann die Daten im CMS ändere, wie der Cache ungültig gemacht und von dev , jedoch ohne next.js zu stoppen und erneut auszuführen :)

Wenn ich sie in einem Modul zwischenspeichere und dann die Daten im CMS ändere, wie der Cache ungültig gemacht und von dev , jedoch ohne next.js zu stoppen und erneut auszuführen :)

getStaticPaths wird nur in einem Produktionsbuild aufgerufen, daher können Sie die Abrufmethode nur anweisen, im Modulstatus zwischenzuspeichern, wenn sie von dieser Funktion aufgerufen wird.

Hey, ich habe nicht gesehen, ob jemand das gleiche Problem hat wie ich.

Angenommen, ich habe dieselbe Seite auf mehreren Routen mit unstable_getStaticProps :

1. /providers/[category]/[city] 
2. /providers/[category] 

Der Quellcode ist für beide Seiten gleich, so dass er nicht dupliziert werden muss. Die erste Datei enthält also Quellcode mit Logik, die zweite importiert nur die erste wie export { default } from './[city]'; .

Es wird jedoch ein Fehler ausgegeben, dass die Daten von getStaticProps nicht definiert sind. Wenn ich denselben Code in beide Dateien kopiere, funktioniert es.

@homoky Sie müssen die Methoden erneut exportieren:

export { default, unstable_getStaticProps } from './[city]';

Ich habe es mit SSG versucht, aber ohne Glück.

Sollte der folgende Code mit v9.2.1 zu SSG führen?

function Page({ stars }) {
  return <div>Next stars: {stars}</div>
}

Page.unstable_getStaticProps = async ctx => {
  return { props: { stars: 5 } }
}

export default Page

Meine Konsolenausgabe von next build zeigt:

Page                                                           Size     First Load
┌ ○ /                                                          354 B       72.1 kB
...
λ  (Server)  server-side renders at runtime (uses getInitialProps or getServerProps)
○  (Static)  automatically rendered as static HTML (uses no initial props)
●  (SSG)     automatically generated as static HTML + JSON (uses getStaticProps)

@joostmeijles unstable_getStaticProps muss exportiert statt an die Seitenkomponente angehängt werden, zB

export const unstable_getStaticProps = async () => {
  return {
    props: { stars: 5 }
  }
}

@joostmeijles unstable_getStaticProps muss exportiert statt an die Seitenkomponente angehängt werden, zB

export const unstable_getStaticProps = async () => {
  return {
    props: { stars: 5 }
  }
}

Danke, das löst es.

Wenn jemand ein End-to-End-Arbeitsbeispiel dafür sehen möchte, das Erstellen dynamischer Seiten (aus einem CMS) mit einer Catch-All-Route und SSG, besuchen Sie https://github.com/agility/agilitycms-next-starter- ssg.

Ich war ein paar Mal ratlos und dachte, dies könnte für andere hilfreich sein.

Wie kann ich während des Builds mit getStaticProps bei der Bereitstellung auf zeit.co/now auf die nächsten API-Routen zugreifen? Isomorpher Abruf erfordert eine absolute URL; lokal funktioniert es mit http://localhost :3000 aber nicht mit now Deployment (oder ich habe es falsch gemacht 🤷‍♂️). Irgendwelche Ideen?

Wenn ich richtig liege, werden die API-Routen als serverlose Funktionen bereitgestellt, und ich vermute, dass sie während des Build-Prozesses nicht bereit sind?

Sie sollten die Funktion Ihrer API-Route direkt aufrufen, da dies viel weniger Overhead bedeutet, als über http zu gehen.

Sie sollten die Funktion Ihrer API-Route direkt aufrufen, da dies viel weniger Overhead bedeutet, als über http zu gehen.

Gibt es Ressourcen, die ich in den Dokumenten zu diesem Thema lesen kann? Ich bin mitten in der Migration zu zeit.co/now :)

Ganz wörtlich genommen importieren und rufen Sie die Funktion auf:

import MyFunction from '../lib/somewhere'


export async function /* unstable_ */getStaticProps() {
  const result = await MyFunction()
}

Noch eine Frage: Wird es möglich sein, getStaticProps / getStaticPaths und getServerProps nebeneinander zu verwenden? Wenn ich zum Beispiel einige Seiten mit SSG vorgerendert habe, aber keine im CDN-Cache gefunden wird, wird dann auf SSR zurückgegriffen, um die Seite bei Bedarf zu generieren?

getStaticProps wird auf SSR zurückgreifen und das Ergebnis zum Cache hinzufügen.

getStaticProps wird auf SSR zurückgreifen und das Ergebnis zum Cache hinzufügen.

@lfades , wenn ich dich richtig verstehe, dann bin ich super 😍 darüber, denn so kann ich ein paar der beliebten Seiten vorrendern, anstatt vorher mehrere tausend Seiten nachzuschlagen und zu generieren.

Aber nur um sicher zu gehen, dass ich es verstehe... Nehmen wir an, ich habe eine /products/[productId].js dynamische Pfadseite. Wenn ich ein getStaticProps und eine begrenzte Anzahl von Ergebnissen aus getStaticPaths anliefere, dann sagen Sie, wenn /products/123 nicht im CDN-Cache gefunden wird (weil es nicht t in getStaticPaths ), wird es auf SSR zurückfallen, getStaticProps ausführen und das Ergebnis dann als statische Seite zwischenspeichern?

Folgefrage: Funktioniert das auch, wenn ich gar kein getStaticPaths liefere?

@flintinatux Ja und ja

getStaticProps wird auf SSR zurückgreifen und das Ergebnis zum Cache hinzufügen

Dies ist ein Problem, da es keine Möglichkeit gibt, 404s auszuführen, da getStaticProps das Ändern des res -Objekts nicht zulässt - entweder 200 oder 500, wenn während des Funktionsaufrufs ein Fehler auftritt.

Ist eine Änderung geplant?

@davidbailey00 beim Erstellen statischer Websites haben 404-Seiten bereits den 404-Statuscode nicht.

Wenn ich einen vollständigen statischen Export durchführe, gibt es natürlich keine Möglichkeit, Statuscodes zu erstellen, da alles nur eine Datei ist. Ich spreche von der Bereitstellung hybrider Sites mit getStaticProps für ZEIT Now - es scheint, als ob es getStaticPaths respektieren und 404-Seiten bereitstellen sollte, anstatt das Rendern aller Seiten zu erzwingen, die unabhängig davon einem dynamischen Pfad entsprechen.

So funktioniert es aber nicht nur bei Now, sondern auch bei next start .

Ich wiederhole, wie bereits gesagt: Dies ist experimentell und alles kann sich noch im Verhalten ändern.

Aber es ist möglich , 404 Seiten mit dienen getServerProps oder getInitialProps - wenn getStaticProps ignoriert getStaticPaths , wenn Antwortcode bedenkt , dann ist es völlig unrentabel für jede Website , die Sorgen über gute SEO.

Wir werden wahrscheinlich weitere Möglichkeiten zum Umgang mit Statuscodes einführen, aber bedenken Sie, dass die meisten statischen Sites (z. B. CRA) /* an index.html weiterleiten, wobei 404 immer noch eine 200 ist.

Hallo Leute, ich habe eine direkte Frage, ich baue eine einfache Website mit dem neuen [unstable_]getStaticProps um einige der Seiten zu SSG. Bisher funktioniert alles einwandfrei, mit Ausnahme des Verstärkers .

Wenn eine Seite [unstable_]getStaticProps , ist amp deaktiviert. Hier ein einfaches Beispiel für die Arbeit mit next v9.2.1, wo Sie das überprüfen können:

import React from "react";
import { useAmp } from "next/amp";

export const config = { amp: `hybrid` };

const AmpExample = ({ date }) => {
  const isAmp = useAmp();
  return (
    <>
      <p>
        Welcome to the {isAmp ? `AMP` : `normal`} version of the Index page!!
      </p>
      <p>date: {date}</p>
    </>
  );
};
/**
 * If I get the dynamic data from getStaticProps,
 * page is SSG render but AMP is disabled when accessing
 * with `/ampExample?amp=1`
 */
export async function unstable_getStaticProps() {
  return {
    props: {
      date: new Date().toISOString(),
    },
  };
}

/**
 * If I get the dynamic data from getInitialProps,
 * page is SSR render but AMP is disabled when accessing
 * with `/ampExample?amp=1`
 */
// AmpExample.getInitialProps = () => {
//   return { date: new Date().toISOString() }
// }
export default AmpExample;

Irgendwelche Hilfe zu verstehen, wie man Seiten SSG mit Daten und amp Laufen bringt?

Hallo, wie wäre es mit getStaticProps für App Komponente ( _app.tsx ), dh für Fälle wie das Abrufen gemeinsamer Daten für alle Seitenkomponenten während der Build-Phase?

Hallo, wie wäre es mit getStaticProps für App Komponente ( _app.tsx ), dh für Fälle wie das Abrufen gemeinsamer Daten für alle Seitenkomponenten während der Build-Phase?

@pkral78 Ich kann Ihnen sagen, wie ich mit dem tatsächlichen Entwicklungsstand

Ich habe ein Layout mit dem Ansatz "Layout as a Higher Order Component (HOC)" erstellt (nicht mehr in den Lernunterlagen 🤷‍♂️).

Wie auch immer, ich habe ein Layout wie das folgende erstellt (nur ein Beispiel):

import React from "react";
import Head from "next/head";

const withSSGLayout = Page => {
  const WithSSGLayout = props => {
    return (
      <>
        <Head>
          <title>My Web Page</title>
          <link rel="icon" href="/favicon.ico" />
          <meta name="viewport" content="width=device-width, initial-scale=1" />
          <link
            href="https://fonts.googleapis.com/css?family=Roboto:400,700&display=swap"
            rel="stylesheet"
          />
        </Head>
        <Page {...props} />
      </>
    );
  };

  WithSSGLayout.unstable_getStaticProps = async () => {
    const pageStaticProps = Page.unstable_getStaticProps
      ? await Page.unstable_getStaticProps()
      : {};

    // Here you can make parent level queries too
    return {
      props: {
        ...pageStaticProps.props,
        parentProp: `dynamic prop-${new Date().toISOString()}`,
      },
    };
  };
  return WithSSGLayout;
};

export default withSSGLayout;

Und dann auf der Seite, auf der Sie diesen Ansatz verwenden möchten, können Sie einfach den HOC hinzufügen (Sie müssen die [unstable_]getStaticProps explizit exportieren und der Verstärker funktioniert nicht zusammen), aber ich habe einen "schönen Weg" gefunden, um eine Anfrage auf hoher Ebene zu stellen und SSG-Abfragen pro Seite.

import React from "react";
import withSSGLayout from "../hocs/withSSGLayout";

export const config = { amp: `true` };

const Index = props => {
  const { date, parentProp } = props;
  return (
    <div>
      <h1>Example</h1>
      <h3>Local Prop?: {date}</h3>
      <h3>Parent Prop?: {parentProp}</h3>
    </div>
  );
};

// In theory you could do direct database queries
Index.unstable_getStaticProps = async () => {
  // Here you can make page level queries
  return {
    props: {
      date: new Date().toISOString(),
    },
  };
};
const IndexHOC = withSSGLayout(Index);

export const { unstable_getStaticProps } = IndexHOC;
export default IndexHOC;

Würde gerne hinterfragen, wenn es ein guter Ansatz ist. In meinem Fall verwende ich diese Technik, um die Links im übergeordneten und den Seiteninhalt in den Seiten abzufragen. Ich hoffe, es hilft.

@robertovg Sie müssen auf

@timneutkens Könnten Sie vielleicht eine bessere Lösung für dieses kleine Beispiel vorschlagen? Ich habe nur versucht, in irgendeiner Weise sowohl "Layout-Level-SSG-Abfrage" als auch "Seiten-Level-SSG-Abfrage" zu haben, und ich dachte über diesen HOC-Layout-Ansatz nach.

Die Haupteinschränkung für mich bestand darin, explizit "[unstable_]getStaticProps" zu exportieren, die Sie auf jeder Seite haben müssen, um sie als SSG-Seite zu markieren.

Ich würde mich auch sehr über weitere Informationen freuen, ob Verstärker + SSG kompatibel sein werden, habe ich vorhin gefragt.

Danke 🙏

@robertovg Trennen Sie zuerst das Layout von den Daten, damit Sie für das freigegebene Layout etwas Einfaches wie

import Layout from '../components/layout'

const Page = () => (
  <Layout>
    <h1>Hello World!</h1>
  </Layout>
)

export default Page

Und dann für getStaticProps die freigegebenen Daten mit einer Methode aus einem anderen Modul abrufen, sodass das vollständige Beispiel so aussehen könnte:

import fetchSharedData from '../lib/fetch-shared-data'
import Layout from '../components/layout'

export const unstable_getStaticProps = async () => {
  const sharedData = await fetchSharedData()
  const pageProps = {...}

  return {  props: { ...sharedData, ...pageProps } }
}

const Page = () => (
  <Layout>
    <h1>Hello World!</h1>
  </Layout>
)

export default Page

@robertovg Trennen Sie zuerst das Layout von den Daten, damit Sie für das freigegebene Layout etwas Einfaches wie

import Layout from '../components/layout'

const Page = () => (
  <Layout>
    <h1>Hello World!</h1>
  </Layout>
)

export default Page

Und dann für getStaticProps die freigegebenen Daten mit einer Methode aus einem anderen Modul abrufen, sodass das vollständige Beispiel so aussehen könnte:

import fetchSharedData from '../lib/fetch-shared-data'
import Layout from '../components/layout'

export const unstable_getStaticProps = async () => {
  const sharedData = await fetchSharedData()
  const pageProps = {...}

  return {  props: { ...sharedData, ...pageProps } }
}

const Page = () => (
  <Layout>
    <h1>Hello World!</h1>
  </Layout>
)

export default Page

Ich sehe und verstehe diese Lösung, aber das Problem, das ich zu lösen versuchte, bestand darin, die Nutzung gemeinsamer Daten zu skalieren.
Zum Beispiel, wenn Sie ein <Header /> , das die sharedData , um die Links zu erhalten und diese von einem Headless CMS kommen. Sie müssen das <Header /> als Kind des <Layout /> mit Requisiten oder einer anderen Lösung injizieren. Und Sie müssen die Injektion von <Header /> in alle Seiten wiederholen, die Sie verwenden möchten.

Beim HOC-Ansatz würden Sie <Header /> einmal im HOC hinzufügen.

Aus diesem Grund dachte ich, es sei ein guter Punkt, der von @pkral78 angesprochen wurde, um Codeduplizierung nach Möglichkeit zu vermeiden.

Aus diesem Grund dachte ich, es sei ein guter Punkt, der von @pkral78 angesprochen wurde, um Codeduplizierung nach Möglichkeit zu vermeiden.

Es war in meinem Kopf. Die _app-Seite sollte ihre getStaticProps , die einmal während des Renderns der ersten Seite aufgerufen werden und dann gespeicherte props an die nächsten gerenderten Seiten weitergeben. Aber ich überlege noch, ob es überhaupt das richtige Konzept ist.

Ich bin mir nicht sicher, ob so etwas ein beabsichtigter Anwendungsfall ist, aber es scheint nicht zu funktionieren:

// /pages/[...slug].jsx
import ReactDOMServer from "react-dom/server";

export async function unstable_getStaticProps({ params: { slug } }) {
  const filePath = "../content/" + slug.join("/") + ".mdx";
  const { default: Component } = await import(filePath);
  const content = ReactDOMServer.renderToStaticMarkup(<Component />);
  return {
    props: { title: slug.join(" "), content }
  };
}

export default function Page({ title, content }) {
  return (
    <div>
      <h1>{title}</h1>
      <div dangerouslySetInnerHTML={{ __html: content }} />
    </div>
  );
}

Auch wenn es kein beabsichtigter Anwendungsfall ist, protokolliert es einen Fehler, der etwas verdächtig erscheint:

[ warn ]  ./pages/[...slug].jsx
Critical dependency: the request of a dependency is an expression

Bearbeiten:

Oh, ok, es löst sich auf, wenn ich es tue

const { default: Component } = await import(`../content/${slug.join("/")}.mdx`);

https://codesandbox.io/s/happy-oskar-40bug

Dies beschwert sich darüber, dass Ihr Importdateipfad dynamisch ist

Am Do, 30. Januar 2020 um 00:29 Uhr schrieb Jan Potoms [email protected] :

Bin mir nicht sicher ob sowas
https://codesandbox.io/s/nifty-cache-jspqr ist ein beabsichtigter Anwendungsfall, aber
es scheint nicht zu funktionieren:

// /pages/[...slug].jsximport ReactDOMServer von "react-dom/server";
asynchrone Funktion exportieren unstable_getStaticProps({ params: { slug } }) {
// Wie sicher ist das überhaupt?
const filePath = "../content/" + slug.join("/") + ".mdx";
const { default: Component } = wait import(filePath);
const content = ReactDOMServer.renderToStaticMarkup(Komponente);
Rückkehr {
Requisiten: { title: slug.join(" "), content }
};
}
Standardfunktion exportieren Seite({ Titel, Inhalt }) {
Rückkehr (


{Titel}




);
}

Auch wenn es kein beabsichtigter Anwendungsfall ist, protokolliert es einen Fehler, der wie
etwas verdächtig:

[ warnen ] ./pages/[...slug].jsx
Kritische Abhängigkeit: Die Anforderung einer Abhängigkeit ist ein Ausdruck


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/zeit/next.js/issues/9524?email_source=notifications&email_token=AAADKRKOL34WKTG7J5QFRJ3RAIGPBA5CNFSM4JRPBEL2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDNPJ
oder abmelden
https://github.com/notifications/unsubscribe-auth/AAADKRIWNA2DSMWFRGD453DRAIGPBANCNFSM4JRPBELQ
.

Aus diesem Grund dachte ich, es sei ein guter Punkt, der von @pkral78 angesprochen wurde, um Codeduplizierung nach Möglichkeit zu vermeiden.

Es war in meinem Kopf. Die _app-Seite sollte ihre getStaticProps , die einmal beim Rendern der ersten Seite aufgerufen werden und dann gespeicherte props an die nächsten gerenderten Seiten weitergeben. Aber ich überlege noch, ob es überhaupt ein richtiges Konzept ist.

@pkral78 , Es könnte daran liegen, dass ich in den meisten SSG-Sites, die ich mir vorstelle, mit Next implementiert zu haben, ein "gemeinsames Stück" (Kopfzeile, Fußzeile, Seitenleisten ...) haben möchte. Und warum nicht einfach die Abfrage nach diesem gemeinsamen Teil in der _app machen, wenn Sie es brauchen, und es auf untergeordneten Seiten verfügbar machen, ohne auf jeder Seite manuell arbeiten zu müssen.

Meine einzige Sorge ist, dass, wenn Sie es in _app.js , wir je nach Seite nicht mehr als ein "gemeinsames Stück" haben können. Mit der Idee, ein Prototyp zu erstellen, wollte ich es im Layout haben, weil es uns ermöglicht, mehrere Layouts zu haben, abhängig von der Art der Seite, die Sie rendern möchten. "Deshalb habe ich withSSGLayout angerufen mein HOC, weil ich plante, nicht nur SSG-Seiten, sondern auch SSR- und vollständig Client-basierte Seiten oder sogar mehr als ein SSGLayout zu haben.Ich könnte dies tun, wenn Layouts auch für eine übergeordnete getStaticProps Methode verantwortlich sein könnte.

Wie auch immer, SSG in Next wird es zum Werkzeug für jede Art von Website machen 🙌

@Janpot bezüglich https://github.com/zeit/next.js/issues/9524#issuecomment -580012327

Kann dringend empfehlen, niemals dynamische Pfade in import() . Es bündelt jede mögliche Datei unter dem Pfad zum JS-Bundle und reduziert dabei die Build-Leistung erheblich.

@timneutkens Klar, macht Sinn. Soll getStaticProps nur externe APIs abfragen, nicht das Dateisystem?

@Janpot Sie können aus dem Dateisystem lesen, oft werden Sie jedoch eine externe API abfragen.

@timneutkens Ok, dann besser @mdx-js/runtime , anstatt sich auf @next/mdx denke ich.

import ReactDOMServer from "react-dom/server";
import { promises as fs } from "fs";
import MDX from "@mdx-js/runtime";

export async function unstable_getStaticProps({ params: { slug } }) {
  const mdxContent = await fs.readFile(`./content/${slug.join('/')}.mdx`, {
    encoding: "utf-8"
  });
  const content = ReactDOMServer.renderToStaticMarkup(<MDX>{mdxContent}</MDX>);
  return {
    props: { title: slug.join(" "), content }
  };
}

export default function Page({ title, content }) {
  return (
    <div>
      <h1>{title}</h1>
      <div dangerouslySetInnerHTML={{ __html: content }} />
    </div>
  );
}

@Janpot ja! Sie könnten auch einfachen Markdown verwenden, das machen wir für nextjs.org/docs.

In Bezug auf https://github.com/zeit/next.js/issues/9524#issuecomment -580207073 ist es genau so, wie ich Next mit SSR derzeit verwende. Ich habe eine GraphQL-Anforderung, die auf Layoutebene ausgeführt wird und deren Inhalt mit den allgemeinen Komponenten der App (Navbar, Fußzeile und die dynamischen untergeordneten Elemente) geteilt wird. Dann stellen die dynamischen untergeordneten Elemente normalerweise eine weitere GraphQL-Anfrage für seitenspezifischen Inhalt.

Daher scheint es wichtig zu sein, dies wiederzuverwenden, und ich möchte nicht auf jeder Seite Code duplizieren müssen, um diese gemeinsamen Daten abzurufen.

Hey!
ich bin ganz neu hier. Ich habe gerade angefangen, an der Migration der App zu NextJS zu arbeiten.

Es gibt einen grundlegenden Anwendungsfall, der von dieser Funktion stark profitieren würde – mehrere Sprachversionen. Die Web-App, an der ich arbeite, hat ungefähr 16 Sprachversionen mit 100.000+ Seitenaufrufen pro Tag und die Möglichkeit, zum Beispiel eine Landingpage statisch zu generieren, wäre fantastisch, aber das Problem ist das Routing.

Mit serverseitigem Rendering kann ich Anforderungsheader oder Cookies lesen und die richtige Sprachversion rendern, aber ist ohne sie die einzige Lösung, um Pfade für jede Version wie /en, /de, /fr und auf "/" zu erstellen, um NextJS einfach umzuleiten?

Nachdem ich etwas über ReactDOMServer.renderToStaticMarkup gelernt hatte, fügte ich es meiner unstable_getStaticProps Funktion hinzu und stellte fest, dass es meinen (mobilen) PageSpeed-Score von 96 auf 100 verbesserte, dank der drastischen Verbesserung der Zeit bis zur Interaktivität und des maximalen Potenzials der ersten Eingabeverzögerung .

Ich kann die Seite ohne JavaScript besuchen und sie lädt gut. Es scheint also, dass React trotz der Verwendung von SSG am Seitenladen arbeitet.

Vielleicht ist dies ein Mangel an meinem Verständnis von React, aber ich würde erwarten, dass die Leistung mit und ohne JavaScript gleich ist, und ich würde nicht erwarten, dass das Vorrendern der Komponenten hilft (ich dachte, das macht SSG).

Ist das Erwartete ein Fehler oder mache ich etwas falsch?

Pre-Commit: https://developers.google.com/speed/pagespeed/insights/?url=https%3A%2F%2F5e310826bcf5030008a91209--josephduffynextjs.netlify.com%2Fposts%2Fgathered-1-0-1&tab=mobile
Commit: https://github.com/JosephDuffy/josephduffy.co.uk/pull/54/commits/d23898b874e5088ebcfabf577ee396b476ed97e4
Post-Commit: https://developers.google.com/speed/pagespeed/insights/?url=https%3A%2F%2F5e3371beda1b8f0009368ef9--josephduffynextjs.netlify.com%2Fposts%2Fgathered-1-0-1&tab=mobile

@JosephDuffy

es scheint also, dass React trotz der Verwendung von SSG beim Laden der Seite arbeitet.

Es hydratisiert das DOM. Grundsätzlich:

  1. Ihr Browser lädt das SSR-HTML in das Browser-DOM
  2. React baut das gesamte virtuelle DOM neu auf
  3. React durchläuft diese DOMs und synchronisiert sie (Hydratation)

Wenn Ihr Inhalt wirklich statisch ist, also keine Nebenwirkungen oder Ereignishandler, dann sind Schritt 2. und 3. irgendwie unnötig. Mit Ihrer Methode reduzieren Sie Ihren Komponentenbaum im Grunde auf 1 Komponente mit 1 Attribut, was für React sehr schnell gerendert und hydratisiert wird. (+ dangerouslySetInnerHTM wird während der Flüssigkeitszufuhr ignoriert)

<div dangerouslySetInnerHTML={{ __html: props.htmlContent }} />

Beachten Sie, dass Ereignishandler und Nebenwirkungen mit dieser Methode nicht funktionieren.

Bearbeiten:

Eine Idee könnte darin bestehen, den Standardexport auf einer Seite wegzulassen, wenn getStaticProps statisches HTML zurückgibt. dh

export async function unstable_getStaticProps() {
  // ...
  return {
    props: { dangerouslySetInnerHTML: { __html: '<div>static content</div>' } }
  };
}

Da clientseitig nichts gerendert werden muss, kann next.js seine Laufzeit von der Seite ausschließen und einfach den HTML-Code einfügen, der getStaticProps zurückgegeben hat. Und es würde genauso funktionieren, als ob dangerouslySetInnerHTML auf dem next.js-Root-Knoten verwendet würde.
Ich denke, es wäre einfacher zu implementieren als eine teilweise Flüssigkeitszufuhr, wenn auch weniger stark. Die Wiederverwendung der Terminologie von React selbst könnte die Verwirrung über die Funktionsweise dieser Funktion verringern.

Ich versuche, eine statische Site zu Next.js zu migrieren, und möchte alle .html-Varianten von Blog-Posts auf Versionen umleiten, die nicht auf .html enden. Es scheint, als würde getStaticProps derzeit keinen Kontext abrufen, sodass ich keine Überprüfung auf eingehenden Slug und keine Umleitung durchführen kann. Es wäre hilfreich, wenn getStaticProps den vollständigen Kontext hätte, damit ich einige bedingte Dinge damit tun könnte.

@nodabladam es hört sich so an, als ob Sie nach dem Custom Routes RFC suchen: #9081.

Dieser RFC würde es Ihnen ermöglichen, etwas wie folgt zu definieren:

// next.config.js
module.exports = {
  redirects() {
    return [
      // Redirect from the old HTML version of a blog post
      {
        source: "/blog/:post.html",
        destination: "/blog/:post",
        permanent: true
      }
    ];
  }
};

Sie können diese Funktion derzeit unter der Taste experimental ausprobieren:

// next.config.js
module.exports = {
  experimental: {
    redirects() {
      // ...
    }
  }
};

Ich habe getStaticProps und getStaticPathNames in einem meiner Projekte (ca. 8K Seiten) implementiert.

Ausgabedateien werden jedoch auf die 10 KB-Grenze von Dateien pro Bereitstellung angerechnet. Bei 8K-Seiten erhalten Sie 16K Ausgabedateien, da jede Seite auch eine JSON-Datei erhält.

Ist eine Erhöhung dieser Grenze geplant? Oder kann ich diese Grenze umgehen?

Ich habe das gleiche Problem.
Ich verstehe, dass sie dieses Limit anheben wollen, aber ich weiß nicht, wann es eingeführt wird.

Also verwende ich getStaticProps auf allen Seiten und getStaticPaths nur auf einigen von ihnen und es funktioniert (meine Produktseite generiert 70% der Gesamtseiten, also habe ich keine getStaticPaths eingefügt). Ich bleibe unter dem Limit, aber es ist nicht perfekt, der erste Ladevorgang ist ziemlich lang und es ist schwierig, 404-Fehler zu verarbeiten.

Ich habe das gleiche Problem.
Ich verstehe, dass sie dieses Limit anheben wollen, aber ich weiß nicht, wann es eingeführt wird.

Also verwende ich getStaticProps auf allen Seiten und getStaticPaths nur auf einigen von ihnen und es funktioniert (meine Produktseite generiert 70% der Gesamtseiten, also habe ich keine getStaticPaths eingefügt). Ich bleibe unter dem Limit, aber es ist nicht perfekt, der erste Ladevorgang ist ziemlich lang und es ist schwierig, 404-Fehler zu verarbeiten.

Ich hoffe, dass sie das Limit bald anheben, aber ich hoffe, es werden nicht 20K sein.. das wird mir auf lange Sicht nicht reichen.

Ich möchte die ersten Ladezeiten mit getStaticPaths vermeiden. Eventuell muss ich neben Zeit Now nach anderen Lösungen suchen

Next.js macht auch automatisch einen API-Endpunkt verfügbar, der das Ergebnis des Aufrufs von getServerProps zurückgibt. [...] Next.js ruft diesen exponierten API-Endpunkt ab, um die JSON-Daten abzurufen, die in die Requisiten umgewandelt werden, die zum Rendern der Seite clientseitig erforderlich sind.

Next.js ruft Daten von diesem Endpunkt ab, bevor die eigentliche Routenänderung vorgenommen und die Seitenkomponente gerendert wird (zumindest standardmäßig nicht anders). So kann der Benutzer eine extrem bissige Site erleben, weil bestimmte Seiten statisch generiert werden, aber wenn er auf einen Link zu einer SSR-Seite klickt, "hängt" die Site plötzlich, kurz bevor sich die Route ändert.

Gibt es eine empfohlene Möglichkeit, die Komponente _first_ zu laden, damit sie mit Ladeindikatoren, animierten Platzhaltern usw. gefüllt werden kann? (Anstatt sie der aktuellen Seite hinzuzufügen.) Wenn nicht, könnten sie für die neu vorgeschlagenen Funktionen relevant sein? Ich habe es mit einer Kombination aus getInitialProps und Hooks innerhalb der Render-Methode erreicht, aber es fühlt sich chaotisch an.

Ich würde denken, dass dieses UX-Muster (sofortiger Seitenwechsel) von vielen (den meisten?) bevorzugt wird, aber ich habe noch keine Beispiele dafür mit Next.js gesehen. Ich benutze das Framework erst seit ein paar Tagen, also korrigiert mich bitte, wenn ich falsch liege.

Bin echt gespannt auf die neuen Features! Danke für deine Arbeit.

@nicoqh , Ihre Bedenken bezüglich Seitenübergängen sind nicht spezifisch für SSG, da das Aufhängen mit dem aktuellen getInitialProps auftritt. Ich verwende nprogress , um zumindest einen Fortschrittsbalken oben anzuzeigen, während die nächste Seite geladen wird, aber ich sehe auch dieses Beispiel für legitime Seitenübergänge, die näher an das klingen, was Sie beschreiben. Ich habe es nicht selbst ausprobiert, aber ich hoffe, es hilft bei dem, was Sie brauchen:
https://github.com/zeit/next.js/tree/canary/examples/with-next-page-transitions

Es sieht so aus, als würde die zurückgegebene JSON-Datei /_next/data/BUILD_ID/<file>.json AssetPrefix nicht berücksichtigen. Dies führt dazu, dass die Datei für mich in meiner Produktionsumgebung zu 404 wird, da ich ein Setup habe, das erwartet, dass alles _next ein Asset ist, das über CDN läuft. Diese JSON-Dateien sollten letztendlich über das AssetPrefix (CDN) weitergeleitet werden, oder?

Ich habe das gleiche Problem.
Ich verstehe, dass sie dieses Limit anheben wollen, aber ich weiß nicht, wann es eingeführt wird.
Also verwende ich getStaticProps auf allen Seiten und getStaticPaths nur auf einigen von ihnen und es funktioniert (meine Produktseite generiert 70% der Gesamtseiten, also habe ich keine getStaticPaths eingefügt). Ich bleibe unter dem Limit, aber es ist nicht perfekt, der erste Ladevorgang ist ziemlich lang und es ist schwierig, 404-Fehler zu verarbeiten.

Ich hoffe, dass sie das Limit bald anheben, aber ich hoffe, es werden nicht 20K sein.. das wird mir auf lange Sicht nicht reichen.

Ich möchte die ersten Ladezeiten mit getStaticPaths vermeiden. Eventuell muss ich neben Zeit Now nach anderen Lösungen suchen

@erhankaradeniz und @ziltosh sollten wir das generell sehr, sehr bald möchten , können Sie mich direkt [email protected] und sie werden sich um Sie

Ich habe das gleiche Problem.
Ich verstehe, dass sie dieses Limit anheben wollen, aber ich weiß nicht, wann es eingeführt wird.
Also verwende ich getStaticProps auf allen Seiten und getStaticPaths nur auf einigen von ihnen und es funktioniert (meine Produktseite generiert 70% der Gesamtseiten, also habe ich keine getStaticPaths eingefügt). Ich bleibe unter dem Limit, aber es ist nicht perfekt, der erste Ladevorgang ist ziemlich lang und es ist schwierig, 404-Fehler zu verarbeiten.

Ich hoffe, dass sie das Limit bald anheben, aber ich hoffe, es werden nicht 20K sein.. das wird mir auf lange Sicht nicht reichen.
Ich möchte die ersten Ladezeiten mit getStaticPaths vermeiden. Eventuell muss ich neben Zeit Now nach anderen Lösungen suchen

@erhankaradeniz und @Ziltosh sollten wir das generell sehr, sehr bald möchten , können Sie mich direkt [email protected] und sie werden sich um Sie

Danke @kvangundy
Ich habe dich bezüglich dieses Problems auf Twitter kontaktiert ;-)

@erhankaradeniz Können Sie stattdessen eine E-Mail an [email protected] senden ? So landet es korrekt in unserem System.

@flintinatux , danke für den Tipp. Ich habe das Beispiel gesehen und es hilft nicht beim Laden der Seitenkomponente vor dem Laden der Daten, daher sind Platzhalter auf der Seite usw. nicht möglich. Aber ein interessantes Beispiel, danke!

Ich denke, es wird in dieser Ausgabe nicht behandelt, was bedeutet, dass es nicht zum Thema gehört, also werde ich woanders suchen, um es zu diskutieren :)

Ich denke, der Ansatz, getInitialProps in getStaticProps & getServerProps aufzuteilen, ist viel sauberer! Ich habe eine Frage dazu, wie sich dies auf unseren Anwendungsfall auswirkt:
Wir möchten zwei separate Builds erstellen: eine statische Version für unsere Produktseite und eine Version mit SSR für eine Bearbeitungsumgebung.

Ich dachte, ich könnte getStaticProps vs getServerProps abhängig vom Build bedingt als statische Methoden anhängen (ähnlich wie https://github.com/zeit/next.js/issues/9524#issuecomment- 558617056), aber ich bin mir nicht sicher, ob dies möglich ist, sie so wie sie sind bedingt zu exportieren. Irgendwelche Ideen, ob dies je nach Build möglich sein wird, um dynamisch / statisch zu unterstützen?

In Bezug auf:

RFC wird später aktualisiert, um Änderungen widerzuspiegeln, und wird immer noch auf die reale Verwendung in unseren Apps wiederholt.

Ich frage mich, ob es eine Möglichkeit gibt, eine Art Wildcard-Route zu verwenden, um Routen abzufangen, die zum Zeitpunkt des Builds unbekannt sind. Es ist großartig, dass ich statische Seiten beispielsweise aus CMS-Daten rendern kann, aber was ist, wenn jemand ein neues Element hinzufügt? Dafür habe ich keine statische Seite. Dieses Thema kratzt mich schon lange am Kopf.

Ich habe eine dynamische Route eingerichtet, um statische Seiten _pages/[slug].js_ zu rendern. _getStaticPaths_ ruft alle Seiten ab, die ich statisch rendern möchte. Ich habe _getStaticProps_, um die Daten abzufragen und an die Renderfunktion zu übergeben. Alle in _getStaticPaths_ angegebenen Seiten werden beim Build als HTML-Dateien in _.next/server/static_ gerendert. Groß!

Jetzt führe ich npm run start und diese Seiten so aus, wie sie sollten. Das Anfordern einer fehlenden URL (wie _/foo_) generiert jedoch neue statische HTML- und JSON-Dateien in _.next/server/static_. Das ist nicht gut. Wie kann ich den Server dazu bringen, alle anderen URLs zu _pages/_error.js_ umzuleiten?

https://github.com/zeit/next.js/issues/9524#issuecomment -582777067

Auch das decken wir ab.

Jetzt führe ich npm run start und diese Seiten so aus, wie sie sollten. Das Anfordern einer fehlenden URL (wie /foo) generiert jedoch neue statische HTML- und JSON-Dateien in .next/server/static. Das ist nicht gut. Wie kann ich den Server dazu bringen, alle anderen URLs auf pages/_error.js umzuleiten?

Dies ist noch während des Fluges und kein unerwartetes Verhalten im Moment.

Nochmals eine Erinnerung daran, dass Sie eine experimentelle Funktion verwenden und das Verhalten sich jederzeit ändern kann. Die Dinge werden sich ändern und möglicherweise zwischen allen Versionen unterbrechen, während Sie dies verwenden, wenn es nicht stabil ist.

@timneutkens Danke! Ich verstehe die Instabilität. Hast du eine Idee, wie man das handhabt? Ging den Code durch und stellte fest, dass das Ausgeben eines Fehlers in _unstable_getStaticProps_ die Fehlerseite rendert. Dies könnte ein schöner Weg sein. Ich bräuchte nur eine Möglichkeit, den Fehler unverändert an _pages/_error.js_ weiterzuleiten. Ich würde es gerne 404 senden. Jetzt geht es als 500.

Ich habe dies schon einige Male in anderen Threads gepostet, aber "going to _error" ist ein unerwartetes Verhalten, ab sofort sollte Ihre Seite einen 404-Zustand darstellen. Einfach gesagt if(!data.something) { return <My404Component /> } , und dann sollte My404Component noindex Meta-Tags setzen.

Wirklich? Die Dokumentation weist eindeutig darauf hin, _pages/_error.js_ für 404s zu verwenden.

Siehe: https://nextjs.org/docs/advanced-features/custom-error-page

@jiv-e das ist für 404s verursacht durch:

  • Seite nicht gefunden
  • Datei nicht gefunden

Wenn Sie dynamische Routen haben, müssen Sie den Fall "404" wie gesagt behandeln, z. B. wie https://nextjs.org/docs/advanced-features/custom-error-page#reusing -the-built-in-error- Seite

Ich habs! Vielen Dank!

Ich möchte getStaticProps , um Übersetzungs- / Sprachschlüssel zur Build-Zeit abzurufen, da sie sich höchstwahrscheinlich 1-2 Mal im Monat oder sogar pro Jahr ändern werden. Sie benötigen sie auch nicht als JSON / Props innerhalb des DOM. Das Problem ist, dass ich die Schlüssel nicht im Baum an die Komponente weitergeben möchte, in der ich sie tatsächlich verwende. Welche Ansätze eignen sich für meinen Anwendungsfall?

useTranslation() Hook (oder HOC) mit Kontext?

Es wäre schön, wenn AppTree Teil des NextGetStaticProps-Kontexts wäre ( getStaticProps({ AppTree }) ). Andernfalls ist es nicht möglich, Dinge wie apollos getDataFromTree auf ssg auszuführen.

An dieser Stelle planen wir nicht, AppTree-Traversal in getStaticProps zuzulassen, da dies wirklich schlecht für die Leistung ist (konsistentes Feedback von Unternehmen). Wenn Sie getStaticProps zu einer Seite hinzufügen, durchläuft es immer noch getInitialProps von _app, um eine inkrementelle Übernahme zu ermöglichen, sodass es immer noch mit Apollo funktionieren würde.

Es wäre schön, wenn wir gleichzeitig amp: 'hybrid' und SSG- Funktionalität haben könnten.
Dies könnte erreicht werden, indem zwei Dateien für eine Seite wie diese erstellt werden, dh:

  • (SSG) index.html
  • (AMP) index.amp.html

Dies würde es Proxys ermöglichen, basierend auf dem Abfrageparameter ?amp=1 in ein Amp-Dokument aufzulösen.

Es wäre schön, wenn wir gleichzeitig amp: 'hybrid' und SSG- Funktionalität haben könnten.
Dies könnte erreicht werden, indem zwei Dateien für eine Seite wie diese erstellt werden, dh:

  • (SSG) index.html
  • (AMP) index.amp.html

Dies würde es Proxys ermöglichen, basierend auf dem Abfrageparameter ?amp=1 in ein Amp-Dokument aufzulösen.

Genau @Dacturne , das ist der einzige Nachteil, den ich sehe, SSG bereits in Projekten zu verwenden, wie ich vor einiger Zeit in diesem Thread kommentiert habe.

🤞

@jansedlon Ich habe einen Blogbeitrag erstellt, der Ihre Frage beantwortet:

Ich frage mich, ob es eine Möglichkeit gibt, eine Art Wildcard-Route zu verwenden, um Routen abzufangen, die zum Zeitpunkt des Builds unbekannt sind. Es ist großartig, dass ich statische Seiten beispielsweise aus CMS-Daten rendern kann, aber was ist, wenn jemand ein neues Element hinzufügt? Dafür habe ich keine statische Seite. Dieses Thema kratzt mich schon lange am Kopf.

https://paqmind.com/en/blog/ssr-ist-nicht-die-zukunft

(nicht hier posten, weil zu groß)

@ivan-kleshnin Ich habe mal kurz nachgeschaut und es sieht super spannend aus! Du hättest mir vielleicht Hunderte von Stunden erspart! Vielen Dank, ich schaue heute noch genauer darauf zurück.

https://github.com/zeit/next.js/issues/9524#issuecomment -582799948

@jansedlon wie bereits erwähnt, arbeiten wir

@timneutkens Lieben Sie die

Wir haben die neuen getStaticProps / getStaticPaths APIs bei unserer Migration von tinacms.org von Gatsby zu Next.js verwendet, und bisher war es großartig!

Ein Stolperstein, den wir hatten, war die Generierung eines RSS-Feeds. Idealerweise möchten wir es statisch generieren, da der Inhalt, auf den es verweist, statisch generiert wird. Ich sehe derzeit keine Möglichkeit, dies zu tun, also handhaben wir es stattdessen nur serverseitig, indem wir den Inhalt abfragen und XML in die Antwort schreiben.

Gab es Diskussionen über die Unterstützung der statischen Generierung für Nicht-HTML-Inhaltstypen?

FYI Wir haben angefangen, getStaticProps auf zeit zu verwenden und Releases mit dem --prod Flag zu verwenden und der Cache wurde für die Json-Dateien auf neuen Releases nicht geleert. Die Umstellung unserer Produktionsversion auf die Verwendung der Alias-Funktion hat funktioniert und der Cache wurde gelöscht.

Wir haben die neuen getStaticProps / getStaticPaths APIs bei unserer Migration von tinacms.org von Gatsby zu Next.js verwendet, und bisher war es großartig!

Ein Stolperstein, den wir hatten, war die Generierung eines RSS-Feeds. Idealerweise möchten wir es statisch generieren, da der Inhalt, auf den es verweist, statisch generiert wird. Ich sehe derzeit keine Möglichkeit, dies zu tun, also handhaben wir es stattdessen nur serverseitig, indem wir den Inhalt abfragen und XML in die Antwort schreiben.

Gab es Diskussionen über die Unterstützung der statischen Generierung für Nicht-HTML-Inhaltstypen?

Ich dachte es für mich und habe es gerade herausgefunden. Hier meine Skripte:

"scripts": {
    "dev": " next",
    "build": "yarn sitemap && next build",
    "start": "next start",
    "sitemap": "ts-node --project ./cli/tsconfig.spec.json ./cli/generateSitemap.ts"
  },

Bevor next build yarn sitemap , erzeugt dies eine statische Sitemap. Sie können dieselbe Technik verwenden, um beispielsweise alle Daten in json zwischenzuspeichern, die Sie in getStaticProps benötigen, und Sie können sie auf mehreren Seiten wiederverwenden.

RFC aktualisiert, Verhalten von getStaticPaths etwas geändert (Sie müssen jetzt einen paths Schlüssel zurückgeben, dies spiegelt getStaticProps wider, wo props müssen Änderung ist noch nicht in Next.js gelandet.

Außerdem wurde eine Erklärung für das Verhalten von fallback hinzugefügt (bei Bedarf Hintergrundgenerierung von Seiten, die zur Erstellungszeit nicht exportiert wurden).

Führte ein weiteres Update des RFC durch, fügte eine Erklärung für Änderungen in der Clientnavigation in Bezug auf einen Loading Zustand hinzu.

Wir möchten möglicherweise eine Möglichkeit hinzufügen, damit Benutzer wissen, ob der Ladezustand über einen React-Hook gerendert wird 🤔

Tolles Zeug! Ich habe mich nur gefragt, ob es für statisch generierte Seiten eine Möglichkeit geben würde, Daten zwischen mehreren Routen mithilfe einer einzigen JSON-Datei auszutauschen (wie Code-Splitting, aber für Daten)?

Ich bin auf den neuesten canary Build gestoßen und wurde sofort vom neuen Loading Zustand Loading Zustände aufzunehmen.

Ich verstehe den Wunsch nach einem schnelleren TTFB, und das könnte in Zukunft ein Nice-to-have für meine App sein. Aber wäre es möglich, den Zustand Loading einer Opt-in- oder Opt-out- Funktion zu machen, ähnlich wie fallback: false für getStaticPaths ? Vielleicht ein export const enableLoadingState = false auf der Seite oder eine Site-weit im next.config.js .

https://github.com/zeit/next.js/issues/9524#issuecomment -583962425

Nochmals eine Erinnerung daran, dass Sie eine experimentelle Funktion verwenden und dass wir derzeit mit dem Verhalten experimentieren.

Ich habe meine (experimentelle) SSG-Website auf Now bereitgestellt (mit einem Standard-Setup). Es funktioniert gut, aber ich sehe 404-Fehler im Netzwerk-Tab, wenn ich die Site durchsuche. Alle 404-Fehler zeigen auf _next/static/pages/[slug].js .

Ist dies erwartetes Verhalten, während es experimentell ist? Oder sollte ich einige Einstellungen ändern?

@joostmeijles es hört sich so an, als ob Sie nicht die richtigen href und as für next/link angeben . Für dynamische Seiten muss href die Seite href='/[slug]' und as muss die URL as='/slug-1'

Ich erhalte während des Builds 3 Protokolle in der Konsole, ist das ein Fehler?

// Page is showing three logs despite static path only having 2 entries and output generating only two files as intended
export default function Page(props){
    console.log("Page - should only show twice", props); 
    return <><h1>Page</h1></>
}

export async function unstable_getStaticProps(props) {
    console.log("unstable_getStaticProps - should only show twice", props);
    return {
      props
    };

}

export async function unstable_getStaticPaths() {
    console.log("show once")
    return {
        paths: [
        { params: { year: "1901" } },
        { params: { year: "1902" } },
        ]
    }
}

Nein, das wird gemäß fallback im RFC erwartet.

Nein, das wird gemäß fallback im RFC erwartet.

export async function unstable_getStaticPaths() {
    console.log("show once")
    return {
        fallback: false,
        paths: [
        // This renders /blog/hello-world to HTML at build time
        { params: { year: "1901" } },
        { params: { year: "1902" } },
        ]
    }
}

Ich habe versucht, mich abzumelden, aber ich erhalte diesen Fehler.

Fehler: Zusätzliche Schlüssel, die von unstable_getStaticPaths in /[Jahr] zurückgegeben wurden (Fallback) Das einzige zulässige Feld ist derzeit paths

Nochmals eine Erinnerung daran, dass Sie eine experimentelle Funktion verwenden und dass wir derzeit mit dem Verhalten experimentieren und nicht alles implementiert ist.

Wird diese Funktion getStaticProps nur für Seiten verfügbar sein?
Wäre auch für App/Dokument interessant, zum Beispiel eine globale Konfiguration für die Anwendung abzurufen?

Ich habe dies "erfolgreich" implementiert und bin mit den bisherigen Ergebnissen zufrieden. Aber ich frage mich, ob es eine Möglichkeit gibt, nachfolgende Builds "schneller" zu machen? Überprüfen Sie zum Beispiel, ob sich SSG-generierte Seiten nicht geändert haben und generieren Sie diese nicht neu? (Wahrscheinlich Wunschdenken von mir)

@timneutkens Haben Sie Pläne, einen sitemap.xml-Generator für SSG-Seiten hinzuzufügen? Ich spreche nicht einmal von dynamischen Routen, da es meiner Meinung nach einfacher ist, sie vorerst nur für statische Seiten zu implementieren.

@timneutkens Haben Sie Pläne, einen sitemap.xml-Generator für SSG-Seiten hinzuzufügen? Ich spreche nicht einmal von dynamischen Routen, da es meiner Meinung nach einfacher ist, sie vorerst nur für statische Seiten zu implementieren.

Ja, das wäre eine tolle Option. Generiere derzeit selbst einen mit SSR. (aber das Laden der sitemap.xml-Datei dauert lange)

https://github.com/zeit/next.js/issues/9524#issuecomment -585293270

Anfangs nur für Seiten, da nach der Landung andere Arbeiten auf getStaticProps wirken.

https://github.com/zeit/next.js/issues/9524#issuecomment -586957539

Ja, aber nicht als Teil dieses RFC. Es wird ein Follow-up geben, nachdem dies gelandet ist.

@timneutkens Ich denke, die Implementierung für SSG-Seiten ist einfach, weil Sie jedes Mal, wenn Next eine statische Seite erstellt, einen URI in ein Array schieben und dann, wenn es endet, einfach das Array jedem XML-Tag zuordnen, verbinden und in der Mitte einfügen eines <sitemapindex> Tags. getStaticProps könnte einen anderen Schlüssel im Rückgabeobjekt namens excludeFromSitemap so dass standardmäßig alle Seiten in sitemap.xml jedoch mit einer Option zum Opt-out.

Wenn dies der Fall wäre, hätten die Entwickler eine genaue Kontrolle darüber, welche statische Seite in die Sitemap aufgenommen wird (zum Beispiel: wenn die Funktion getStaticPaths Seite [foo] Pfade mit foo params 'abc' und 'xyz' aber nur die 'abc' Datei sollte in der Sitemap sein, der Entwickler könnte excludeFromSitemap auf true wenn der Parameter ==='xyz' in getStaticProps .

Für SSR und statische Seiten könnte es auch möglich sein, eine Konstante (zB export const excludeFromSitemap = true; ) aus der Seitendatei zu exportieren, genau wie getServerProps , getStaticPaths und getStaticProps werden exportiert.

Wenn auf SSG-Seiten eine exportierte excludeFromSitemap Konstante (Seitenstandard) vorhanden ist und sich dieser Schlüssel auch in dem von der getStaticProps Funktion zurückgegebenen Objekt befindet (pfadspezifisch), sollte der exportierte Wert als Standardwert fungieren Wert für alle Pfade auf dieser Seite und das pfadspezifische excludeFromSitemap , wenn es im getStaticProps Objekt vorhanden ist, sollte den Standardwert der Seite überschreiben (so könnte eine Seite export cosnt excludeFromSitemap = true und fügen Sie dann den Schlüssel excludeFromSitemap zu dem von getStaticProps Objekt mit dem Wert false , um alle Pfade mit Ausnahme dieses bestimmten von der Sitemap auszuschließen).

Der Code zum Anhängen an das Array wäre ungefähr so ​​(ich habe die Wahrheitstabelle berechnet und den minimalen booleschen Ausdruck mit einer Karnaugh-Map erhalten):

//...somewhere else
const validExcludeFromSitemapTypes = ['boolean','undefined'];

//...for each path
const isSSG = !!getStaticPropsReturnedObj && typeof getStaticPropsReturnedObj === "object";
if(
    validExcludeFromSitemapTypes.indexOf(typeof pageExports.excludeFromSitemap)<0 ||
    (isSSG && validExcludeFromSitemapTypes.indexOf(typeof getStaticPropsReturnedObj.excludeFromSitemap)<0)
) {
    throw new Error("'excludeFromSitemap' can either be ommited (undefined) or be a boolean");
}
const defaultExcludedValue = !!pageExports.excludeFromSitemap;
const hasSpecificExcluded = isSSG && typeof getStaticPropsReturnedObj.excludeFromSitemap !== "undefined";
const specificExcludedValue =  isSSG ? !!getStaticPropsReturnedObj.excludeFromSitemap : false;

if(!specificExcludedValue && (!defaultExcludedValue || hasSpecificExcluded))
    sitemapURIs.push(correctlyEncodedURI);

Das Umwandeln des Arrays in die Sitemap wäre so einfach (vorausgesetzt, die URIs im Array sind bereits codiert und nach !excludeFromSitemap gefiltert):

function createSitemap(sitemapURIs: string[]): string {
    return `<sitemapindex>${sitemapURIs.map(u=>`<sitemap><loc>u/loc></sitemap>`).join('')}</sitemapindex>`;
}

Ich denke, dieses Feature würde sich gut in Next.JS einfügen, da ein Teil seiner Mission darin besteht, den Benutzern die 100-SEO-Punktzahl zu geben, und ein sitemap.xml würde sehr helfen! ( robots.txt könnte möglicherweise auch generiert werden, indem ein else zur Bedingung hinzugefügt wird, die die Pfade zum Sitemap-Array hinzufügt, um diesen Pfad an ein anderes Array von unzulässigen Seiten anzuhängen)

In der aktuellen Release-Version können Sie bei Verwendung der unstable_getStaticPaths zusammen mit der unstable_getStaticProps Funktion keine API-Aufrufe an Funktionen durchführen, die in /api/ .
Da der Server nicht läuft, ist es unmöglich, auf diese Weise die entsprechenden Anfragen zu stellen und die statischen Requisiten zu generieren.
Sie müssen entweder die Pfadfunktionen nicht bereitstellen (was dieses SSR im Grunde mit einem Cache ausmacht, was immer noch schön ist!) oder auf SSR anstelle von SSG setzen.

Vielleicht wäre dies eine gute Ergänzung für diese Funktion? Ich bin mir nicht sicher, was der beste Weg hier wäre, ich habe woanders einen Vorschlag gelesen, der vorschlug, die http-Anfrage mit SSR und /api Routen zu verkürzen, dies wäre auch hier praktisch.

Aber all dies würde natürlich bedeuten, dass Code in der Build-Umgebung ausgeführt wird, der Aufrufe zu anderen Diensten / DB-Aufrufen oder ähnlichem machen würde. Dies sollte klargestellt werden, wenn dies implementiert wird, aber es wäre eine coole Ergänzung für dieses Feature.

@reckter Ja , ich habe gerade selbst etwas Ähnliches gemacht. Ich musste für jede einzelne separate Seitenanforderung eine Verbindung zu meiner Datenbank herstellen, während sie statisch generiert wurde. Fühlte sich sehr seltsam an...

Ich hoffe, das ist nicht der letzte Anwendungsfall

Es wäre schön, eine Art Initialisierungsskript zu haben, das Sie aus der next.config oder so einrichten können ...

@reckter Eine Möglichkeit, HTTP-Anfragen mit API-Routen von SSG/SSR zu

Wie auch immer, eine mögliche Lösung für den Zugriff auf API-Routen während SSG wäre, einen lokalen Server zu haben, der nur die /api Routen ausführt, bevor die statischen Seiten kompiliert werden! Die Build-Schritte wären also:

  1. Starten Sie einen Server (vielleicht "Api-Kompilierungsserver" oder so ähnlich), der nur die /api Routen bedient
  2. unstable_getStaticPaths
  3. unstable_getStaticProps
  4. Kompilieren Sie die statischen Seiten

@reckter im Grunde müssen Sie keine API-Routen aufrufen, Sie können die von ihr implementierte Funktion direkt aufrufen. Dies vermeidet auch einen Großteil des Overheads, der über http-Ursachen hinausgeht.

Grundsätzlich, wenn Sie derzeit eine API-Route haben, die wie folgt aussieht:

import myDb from 'mydatabaseprovider'
const db = myDb()

export default async (req, res) => {
  cont myData = await db.query('posts')
  res.json(myData)
}

Sie würden es ändern in:

import myDb from 'mydatabaseprovider'
const db = myDb()

export async function getData() {
  const myData = await db.query('posts')
  return myData
}

export default (req, res) => {
  const myData = await getData()
  res.json(myData)
}

Und dann auf deiner Seite:

import {getData} from './api/myfunction'

export async function getStaticProps() {
  const myData = await getData()
  return {
    props: {
     myData
   }
  }
}

Es wäre schwierig, dasselbe für GraphQL-APIs zu tun. Und auch für die meisten REST.

API-Aufruf != Abrufen von DB (allgemein)
Es gibt fast immer eine gewisse Geschäftslogik in der API-Schicht wie Feldumbenennung, Datenneuformatierung usw.

Ich bin sicher, Sie haben Gründe, pages/api Aufrufe zu verbieten... aber die Umgehung einer echten API wird nicht einfach oder billig sein. Und ein paar eingesparte Millisekunden werden die Gebühren für Extracode/Komplexität IMO nicht aufwiegen.

Es fühlt sich auch seltsam an, dass Anfragen an jede API zulässig sind. Außer deinem eigenen

Wenn Sie unstable_getStaticPaths wird die Seite neu geladen und verliert beispielsweise den aktuellen Status in Redux. Wird sich dieses Verhalten in Zukunft ändern?

Bearbeiten: scheint dieses Verhalten durch Verwendung der Option as in Links oder Routern umgangen werden zu können

<Link
  href='/item/[key]'
  as={`/item/${itemName}`}
>
router.push(
  '/item/[key]',
  `/item/${itemName}`
);

@meesvandongen das war schon immer so. Wenn Ihr <Link> ungültig ist, gelangen Sie zum Backend-Teil, der im Grunde als <a> . Dynamische Fragmente wie [key] müssen mit entsprechenden Werten gepaart werden.

@reaktivo pages/[lang]/blog/[id].js -> in getStaticPaths alle URLs zum statischen Rendern angeben.

https://github.com/zeit/next.js/issues/9524#issuecomment -562625858
In diesem Fall müssen für jede Seite außer index.js die Funktionen getStaticPaths und getStaticProps hinzugefügt werden.
Wenn es einige mdx-Seiten gibt, ist das Projekt schwieriger zu pflegen

Erwägen Sie eine Änderung oder Kompatibilität mit statischen getStaticPaths getStaticProps Methoden. https://github.com/zeit/next.js/issues/9524#issuecomment -558617056
Wenn dies der Fall ist, kann die Seite durch eine Funktion höherer Ordnung oder eine Komponente höherer Ordnung (HOC) umbrochen werden.
Auf diese Weise ist der Code wartungsfreundlicher und für Typescript bequemer.


Baumschütteln vs. dynamisch. Was für ein Kopfschmerz-Trade-off.😂

Mit 9.2.3-canary.13 ich versucht, fallback: false in getStaticPaths wie folgt zu verwenden:

  return {
    fallback: false,
    paths: slugs.map(slug => ({params: {slug: slug}}))
  }

aber es schlägt mit folgendem Fehler fehl:

Error: Extra keys returned from unstable_getStaticPaths in /blog/[slug] (fallback) Expected: { paths: [] }

Mit 9.2.3-canary.13 ich versucht, fallback: false in getStaticPaths wie folgt zu verwenden:

  return {
    fallback: false,
    paths: slugs.map(slug => ({params: {slug: slug}}))
  }

aber es schlägt mit folgendem Fehler fehl:

Error: Extra keys returned from unstable_getStaticPaths in /blog/[slug] (fallback) Expected: { paths: [] }

Ich denke, Sie brauchen die Karte eine höhere Ebene, also gibt die Karte das Objekt zurück, das Sie derzeit haben, jedoch mit einer einzigartigen Schnecke. anstatt in den Pfaden zuzuordnen.

Ich habe meine Version auf nextjs noch nicht aktualisiert, aber es sollte ähnlich sein:

return data.map(item => {
    return {
      params: {
        slug: item.slug,
      },
    }
  })

@jorngeorg es ist eine offene PR: https://github.com/zeit/next.js/pull/10701

Fantastischer Beitrag! Es verbessert wirklich den statischen Rendering-Prozess.

Ich empfehle, den Dokumenten hinzuzufügen, dass bei dynamischen Routen der "Fallback" ohne Aufruf von getStaticProps generiert wird - was bedeutet, dass Sie Ihre Komponente codieren müssen, um den Fall zu berücksichtigen, dass props leer ist.

Alternativ können Sie beim Erstellen des Fallbacks das Verhalten so ändern, dass getStaticProps ohne Kontext aufgerufen wird. Dies würde der aktuellen Funktionsweise von next export (zB /p/[id].js wird nach /p/[id].html exportiert, indem getInitialProps ohne Kontext ausgeführt wird).

  • getStaticProps - Melden Sie sich zum Zeitpunkt next build für die statische Generierung (SSG) an.
  • getServerProps - Aktivieren Sie das serverseitige Rendering (SSR), das bei Bedarf rendert.

10722

Benennen Sie getServerProps in getServerSideProps um.

Ich empfehle, den Dokumenten hinzuzufügen, dass bei dynamischen Routen der "Fallback" ohne Aufruf von getStaticProps generiert wird - was bedeutet, dass Sie Ihre Komponente codieren müssen, um den Fall zu berücksichtigen, dass props leer ist.

Guter Punkt, es zu erwähnen! Ich hatte auch einige Build-/Bereitstellungsfehler, weil ich das übersehen habe.

RFC aktualisiert, um die Änderungen widerzuspiegeln

@timneutkens

  • Eine nachfolgende Anfrage an denselben Pfad liefert die generierte Seite

Ich gehe davon aus, dass dies bedeutet, dass Next.js die generierte Seite zwischenspeichert? Ist das ein In-Memory-Cache? Ist dieser Cache durch Grenzen begrenzt oder kann dies zu Speicherlecks führen?

Wenn Sie next start verwenden, wird lru-Cache ähnlich dem aktuellen Caching-Beispiel verwendet. Derzeit beträgt das Standardlimit 50 MB, wir können es später konfigurierbar machen: https://github.com/zeit/next.js/ blob/canary/packages/next/next-server/server/spr-cache.ts#L90

Wenn Sie auf ZEIT hosten, geschieht die Generierung und das Caching auf dem CDN/Proxy, sodass es etwas anders funktioniert und Sie sich keine Sorgen über Speicherlecks oder Überschreitungen des lru-Limits machen müssen.

👍 ok, scheint vernünftig. Das hatte ich mir mehr oder weniger als sinnvolles Standardverhalten vorgestellt.

  • getStaticProps - Melden Sie sich zum Zeitpunkt next build für die statische Generierung (SSG) an.
  • getServerProps - Aktivieren Sie das serverseitige Rendering (SSR), das bei Bedarf rendert.

10722

Benennen Sie getServerProps in getServerSideProps um.

Warum aber die Umbenennung? IMHO getServerProps ist genau genug und kürzer zu tippen, das Hinzufügen von Side fühlt sich für mich überflüssig an.

Ich habe mich gefragt, ob an der getStaticPaths-Methode Änderungen vorgenommen wurden. Meine dynamischen Seiten werden nicht mehr als statische Seiten generiert, sondern jetzt als Lambda-Funktionen exportiert?

Liege ich richtig, wenn das Standardverhalten jetzt darin besteht, dass die Seiten zuerst als Lambdas gerendert werden und erst nach dem Besuch einer bestimmten Seite die Seite zu einer statischen Seite generiert wird? (wie im Fallback erwähnt)

@erhankaradeniz Es wurden keine Änderungen an getStaticPaths , die dazu führen würden, dass Ihre Seite(n) Lambdas sind. Dies ist wahrscheinlich ein Fehler in der Verwendung.

Können Sie bitte Ihren Code zeigen, damit wir das Problem identifizieren können?

@Timer Ich bin vorerst zu

So habe ich derzeit meine Pfade generiert:

return cityData.map(city => {
    return {
      params: {
        country: city.countrySlug,
        city: city.slug,
      },
    }
  })

und auf einer anderen Seite tue ich:

return cityData.map(city => {
    return {
      params: {
        country: city.countrySlug,
        city: city.slug,
      },
    }
  })

habe es nicht geschafft, es mit den Pfaden auf die neue Canary-Version zu konvertieren. Ich muss etwas falsch machen, denn console.logs werden nicht einmal innerhalb von getStaticPath ausgelöst

Ich habe Probleme mit dem Vorrendern von verschachtelten Pfaden und SSG:

// pages/[lang]/[...slugs].js

export async function getStaticPaths() {
  let knex = await import("knex/client").then(m => m.default)
  let pages = await knex("page").select(["lang", "url"])
  return {
    fallback: true,
    paths: pages.map(page => {
      return {
        params: {
          lang: page.lang,
          slugs: page.url == "/" ? [] : page.url.slice(1).split("/"),
        }
      }
    }),
  }
}

führt zu

Error occurred prerendering page "/en/". Read more: https://err.sh/next.js/prerender-error:
Error: The provided export path '/en/' doesn't match the '/[lang]/[...slugs]' page.

für die Startseite. Aus irgendeinem Grund passt NextJS nicht zusammen

{lang: "en", slugs: []}

zu

/[lang]/[...slugs]

Wenn ich {lang: "en", slugs: ["/"]} angebe, wird es erstellt, aber mit einer falschen URL:

├ ● /[lang]/[...slugs]      875 B        204 kB
├   ├ /en/credits
├   ├ /en/%2F

Fürs Protokoll, getServerSideProps funktioniert mit einem ähnlichen Setup gut.

Ich weiß, es ist experimentell, aber dieser Thread soll Feedback geben, oder?

pages/[lang]/[...slugs].js entspricht /en/abcdef und nicht /en , dafür müssen Sie derzeit pages/[lang]/index.js erstellen.

Dafür ist ein Feature Request offen: https://github.com/zeit/next.js/issues/10488

Das ist erstmal toll. Ich habe gehofft, so etwas in Next.js zu haben, damit ich endlich von Gatsby.js wegkommen und eine Hybrid-App (statisch + dynamisch) haben kann.

🚀 Ich habe die kanarische und halbgebackene komplexe App-Version ausprobiert, die gut funktioniert hat. Ich gestehe, ich habe nicht alle Kommentare hier gelesen, bin mir aber nicht sicher, ob das Tree-Shaking noch implementiert ist.

🤔 getStaticPaths fühlt sich viel eher wie setStaticPaths wo wir den statischen Pfad für das SSG-Verhalten definieren. Das hat mich ein bisschen verwirrt.

🧐 Ich frage mich, ob wir die Build-Zeiten verbessern können, indem wir Build-Kategorien haben? Ich weiß, dass dies die Einrichtung erschweren würde, aber es wird sich lohnen. Lassen Sie mich erklären:

Was ist, wenn wir etwas wie setBuildCategory , das es auf blog oder pages oder was auch immer jemand will 2020-content . Dann sucht der SSG-Builder nach der Kategorie der geänderten Seite und versucht nur, diese Kategorie aus einer Kombination aus Cache und neuem Rendering neu zu erstellen. So etwas kann uns helfen, SSG schnell zu machen und riesige Build-Zeiten für Dinge zu vermeiden, die sich nicht viel ändern, sich aber dennoch ändern könnten und daher nicht archiviert werden können.

Wenn das Sinn macht; Ich freue mich, auf einen Anruf zu springen und darüber zu plaudern.

Wie handhabe ich getServerSideProps mit einer benutzerdefinierten Serverimplementierung?

if (pathname === '/a') {
  app.render(req, res, '/b', query)
}

Im obigen Beispiel wird beim Aufrufen von /a die Seite pages/b.js . Aber eine clientseitige Umleitung zu /a versucht, eine a.json Datei herunterzuladen, die in diesem Fall nicht existiert.

Sollen wir ähnliche Bedingungen für Anfragen an /_next/data/{BUILD_ID}/{PAGE}.json , um verschiedene JSON-Dateien zu rendern?

Wie erhalte ich das req-Objekt, um fallback: true in getStaticPaths zu verwenden? Es scheint derzeit, dass ich nicht kann. Der Grund, warum ich es brauche, ist, einige Cookies aus dem Browser zu holen, um eine Route zu authentifizieren

@tylermcrobert wie schnappen, wenn es überhaupt keine Anfrage gibt
Routen mit Backend, die von echten Besucheranfragen abhängen, können nicht durch Definitionen von "statisch" und "dynamisch" statisch gemacht werden. Um nicht zu sagen, dass Sie Static und Authentifizierung nicht kombinieren können ... es ist nur, dass der Authentifizierungsteil zu API- und Client-Code anstelle von Seiten gehört.

Wie handhabe ich getServerSideProps mit einer benutzerdefinierten Serverimplementierung?

if (pathname === '/a') {
  app.render(req, res, '/b', query)
}

Im obigen Beispiel wird beim Aufrufen von /a die Seite pages/b.js . Aber eine clientseitige Umleitung zu /a versucht, eine a.json Datei herunterzuladen, die in diesem Fall nicht existiert.

Sollen wir ähnliche Bedingungen für Anfragen an /_next/data/{BUILD_ID}/{PAGE}.json , um verschiedene JSON-Dateien zu rendern?

Next.js unterstützt dynamische Routenparameter, sodass eine Neuzuordnung in einem benutzerdefinierten Server selten mehr erforderlich ist: https://nextjs.org/docs/routing/dynamic-routes

Der von Ihnen beschriebene Ansatz funktioniert nicht mit <Link> (würde einen vollständigen Seitenübergang verursachen), also funktioniert getServerSideProps bereits.

@tylermcrobert wie schnappen, wenn es überhaupt keine Anfrage gibt
Routen mit Backend, die von echten Besucheranfragen abhängen, können nicht durch Definitionen von "statisch" und "dynamisch" statisch gemacht werden. Um nicht zu sagen, dass Sie Static und Authentifizierung nicht kombinieren können ... es ist nur, dass der Authentifizierungsteil zu API- und Client-Code anstelle von Seiten gehört.

Vielleicht verstehe ich die Fallback-Option in diesem Fall falsch. Was Sie sagen, macht im Kontext der Build-Zeit absolut Sinn.

Ist fallback: true für den Fall, dass es keine vordefinierte Route gibt? In diesem Fall würde ein Fallback vom Browser aus erreicht, nicht wahr?

@tylermcrobert ja fallback: true case hat eine Anfrage, aber die API muss mit dem "kleinsten gemeinsamen Nenner" vereinheitlicht werden. Ich kann mir kein funktionierendes System vorstellen, bei dem alles mit einem Satz von Prämissen erstellt und dann schrittweise mit einem völlig anderen Satz von Prämissen aktualisiert wird. Es wird eine Katastrophe sein, es zu unterstützen.

Ich denke, Sie übersehen den Punkt, dass diese inkrementellen Builds immer noch zwischen Builds zwischengespeichert werden. Die Rolle des ersten Besuchers beeinflusst also das Build-Ergebnis für alle nachfolgenden Benutzer! Klingt nach einer schlechten Idee.

@ivan-kleshnin Ich verstehe und stimme sicherlich zu. Der Grund, warum ich frage, liegt in meinem speziellen Anwendungsfall.

Ich verwende ein Headless-CMS, das eine Vorschaufunktionalität ermöglicht, sodass die Seiten, die in der Vorschau angezeigt werden müssen, zur Build-Zeit nicht enthalten sind (da der in der Vorschau angezeigte Eintrag zu diesem Zeitpunkt noch nicht existiert hat). Ich dachte, dies wäre ein Fall, in dem die Fallback-Option ins Spiel kommen würde.

Um auf diese Vorschau zuzugreifen, benötige ich Zugriff auf die API-Vorschaureferenz, die über ein Cookie bereitgestellt wird.

Ist das ein Fall, in dem ich useStaticProps einfach komplett verschrotten sollte? Ich würde es hassen, die Vorteile statischer Builds zu verlieren, weil ich meine Dokumente nicht in der Vorschau anzeigen kann.

Die Attraktivität dieses RFC gegenüber etwas wie Gatsby besteht darin, dass es uns eine „hybride Kontrolle“ mit statischer Site-Generierung gibt, die die Arbeit mit Headless-CMS erleichtert

Ich verwende ein Headless-CMS, das eine Vorschaufunktionalität ermöglicht, sodass die Seiten, die in der Vorschau angezeigt werden müssen, zur Build-Zeit nicht enthalten sind (da der in der Vorschau angezeigte Eintrag zu diesem Zeitpunkt noch nicht existiert hat). Ich dachte, dies wäre ein Fall, in dem die Fallback-Option ins Spiel kommen würde.

Bleiben Sie dran, bald mehr 🕵

Wenn ich das richtig verstehe, können wir Fallback true verwenden, wenn sich beispielsweise in meinem Fall ein Benutzer registriert (es wird keine statische Seite generiert, da es sich um eine neue Seite/ein neuer Benutzer handelt), aber wenn das Profil einen Besuch erhält, wird es automatisch generiert?

Erhan Karadeniz
http://www.erhankaradeniz.com

Am 4. März 2020 um 20:25 Uhr schrieb Tim Neutkens [email protected] :


Ich verwende ein Headless-CMS, das eine Vorschaufunktionalität ermöglicht, sodass die Seiten, die in der Vorschau angezeigt werden müssen, zur Build-Zeit nicht enthalten sind (da der in der Vorschau angezeigte Eintrag zu diesem Zeitpunkt noch nicht existiert hat). Ich dachte, dies wäre ein Fall, in dem die Fallback-Option ins Spiel kommen würde.

Bleiben Sie dran, bald mehr 🕵


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail, zeigen Sie sie auf GitHub an oder melden Sie sich ab.

Benutzerdaten sind ein schlechtes Beispiel, da Sie diese clientseitig abrufen möchten. Fallback ist für statisch generierte On-Demand-Seiten gedacht, die zur Erstellungszeit nicht generiert wurden. ZB möchten Sie vielleicht die Top 100 Blogposts zur Erstellungszeit generieren und keine anderen mit weniger Traffic generieren.

Docs werden demnächst dafür gelandet.

Ja, was ich meinte, war eine Platzhalterseite. Ich würde tatsächlich Benutzerdaten auf der Clientseite abrufen.

@timneutkens Gibt es eine Möglichkeit, bestimmte statisch generierte Seiten zu löschen oder neu zu erstellen?

Hi!!! Klingt nach der optimalen Anwendung. Ich liebe sowohl React als auch Next!!! Machte alles so elegant und einfach für uns zu bedienen !! Aber das Beispiel enthält den Begriff Blog. Ich möchte ein Beispiel für eine Implementierung bei der Abfrage eines Headless CMS sehen und den Abruf pro Seite/Post als Export als statisches Element durchführen.

// Prost, da es bald Freitag ist !!!

@timneutkens das ist spannend 👌

Ein Szenario, auf das wir häufig stoßen, und ich habe mit next.js oder gatsby noch keine perfekte Lösung, außer dynamische Routen oder das Generieren von Projekten in einer Schleife:

Aus historischen Gründen haben wir es mit mehreren Domains zu tun (und das wollen wir nicht ändern), die die gleichen/genauen Seiten bedienen, mit Ausnahme von Preisen, Währung, Support-Telefonnummern und Sprachauswahl. Von Natur aus sind die meisten dieser Marketingseiten ziemlich statisch und es würde ausreichen, sie täglich oder wöchentlich zu erstellen (statt sie bei jeder Anfrage rendern zu müssen).

Meine Frage/Mein Gedanke: Sehen Sie eine Möglichkeit (in Zukunft?), dass getStaticPaths Seiten basierend auf etwas generieren könnte, das kein Routenparameter ist, sondern auf Anfrageebene verwendet werden könnte, um zwischen ihnen zu wechseln (z. B. serverlos Funktion gibt statisches, vorgefertigtes Ergebnis basierend auf locale )

Konkret würde dies bedeuten, dass https://mysite.com/my-product und https://mysite.co.uk/my-product zwei verschiedene statische Seiten bedienen würden, aber ohne dass wir unsere nächste App 50x generieren oder bei jeder Anfrage ein CMS aufrufen müssten😅

Vielen Dank im Voraus und gespannt auf eure Meinung, vor allem wenn das etwas für die Zukunft ist, das gelöst/umgehbar ist ❤️

Ich denke über einen Anwendungsfall nach, bei dem ich SSG für stark frequentierte Zielseiten für SEO und zur Reduzierung der Serverlast verwenden möchte, aber dennoch möchte, dass aktuelle Daten nach der Hydratation und beim clientseitigen Routing zu dieser Seite verwendet werden. Wäre das möglich?

Grundsätzlich sollte das Verhalten beim clientseitigen Routing zu dieser Seite wie bei getInitialProps (aktuelle Daten werden abgerufen, bevor die Seite sichtbar wird). Und beim serverseitigen Routing zu dieser Seite sollte der statische HTML-Code bereitgestellt und hydratisiert werden und dann (optional) einige API-Antworten abgerufen werden, um einige Daten auf der Seite zu aktualisieren.

Ich habe gerade mit unstable_getStaticProps , um es auszuprobieren, und bin in einen lustigen Konflikt geraten: Es ist schwierig, API-Routen mit getStaticProps .

Achten Sie nicht auf die Semantik des Codes, sondern nur auf den Datenfluss:

// pages/api/healthcheck.ts
import { NextApiResponse, NextApiRequest } from 'next';

export type ApiHealthCheckResponse = {
  message: 'ok';
};

const healthCheckHandler = (
  req: NextApiRequest,
  res: NextApiResponse<ApiHealthCheckResponse | ''>,
) => {
  if (req.method === 'GET') {
    return res.status(200).json({ message: 'ok' });
  }

  return res.status(405).send('');
};

export default healthCheckHandler;
// pages/index.js
// ...

export async function unstable_getStaticProps() {
  return {
    props: {
      healthcheck: (await fetch('localhost:3000/api/healthcheck').json())
    },
  };
}

Die Seitenerstellung stürzt zur Erstellungszeit ab, da der Server nicht ausgeführt wird. Ich bin mir nicht sicher, ob dies ein gültiger Anwendungsfall ist, da getStaticProps nicht mit etwas zu dynamischem verwendet werden sollte, aber ich dachte, es wäre ein interessanter Edgecase zum Teilen (ich kann mir gut vorstellen, dass ein Route-API-Endpunkt dafür verantwortlich ist, Daten von einer anderen API und formatieren Sie sie neu.

@martpie Vielleicht möchten Sie sich diesen Kommentar ansehen: https://github.com/zeit/next.js/issues/9524#issuecomment -589772756

Die Unterstützung für die Static Site Generation (SSG) der nächsten Generation wurde in Next.js 9.3 als stabil veröffentlicht!

Diese Version enthält auch Unterstützung für den "Vorschaumodus" oder die Möglichkeit, die statisch vorgerenderte Seite zu umgehen und die Seite bei Bedarf für autorisierte Benutzer zu rendern .

Mehr dazu können Sie in unserem Blogbeitrag lesen . Wenn Sie mehr praktische Erfahrung haben , springen Sie direkt in unsere

Bitte posten Sie alle Fragen an die Next.js GitHub-Community !

Das ist so cool! Danke für die Mühe!

Dieses neue Feature scheint jetzt nicht mit Saga und Redux zu funktionieren

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

formula349 picture formula349  ·  3Kommentare

knipferrc picture knipferrc  ·  3Kommentare

YarivGilad picture YarivGilad  ·  3Kommentare

renatorib picture renatorib  ·  3Kommentare

DvirSh picture DvirSh  ·  3Kommentare