Next.js: Génération statique / Améliorations SSG

CrĂ©Ă© le 25 nov. 2019  Â·  250Commentaires  Â·  Source: vercel/next.js

Sommaire

Permettez à Next.js de devenir entiÚrement hybride en fournissant des méthodes pour effectuer à la fois la génération statique et le rendu cÎté serveur par page.

  • Deux nouvelles mĂ©thodes de rĂ©cupĂ©ration de donnĂ©es par page

    • getStaticProps - Opt-in Ă  la gĂ©nĂ©ration statique (SSG) Ă  next build time.

    • getServerSideProps - Optez pour le rendu cĂŽtĂ© serveur (SSR) qui rend Ă  la demande.

  • Une nouvelle mĂ©thode pour gĂ©nĂ©rer statiquement (SSG) un ensemble de routes Ă  partir de sources dynamiques

    • getStaticPaths - Retourne la liste des paramĂštres pour les routes dynamiques pour faire la gĂ©nĂ©ration statique (SSG)

Cette RFC traite exclusivement des ajouts d'API. Toutes les nouvelles fonctionnalitĂ©s sont entiĂšrement rĂ©trocompatibles et peuvent ĂȘtre progressivement adoptĂ©es. Cette RFC n'introduit aucune dĂ©prĂ©ciation.

Fond

Lors de la création de sites Web ou d'applications Web, vous devez généralement choisir entre 2 stratégies : la génération statique (SSG) ou le rendu cÎté serveur (SSR).

Next.js vous permet Ă  la place de crĂ©er des applications hybrides qui vous permettent de choisir par page quelle stratĂ©gie est utilisĂ©e. À partir de Next.js 9, les pages sans getInitialProps sont optimisĂ©es statiquement et sorties sous forme .html fichiers next build .

Cependant, vous souhaiterez peut-ĂȘtre rĂ©cupĂ©rer des donnĂ©es tout en gĂ©nĂ©rant des pages statiques pour votre cas d'utilisation spĂ©cifique.

Par exemple, pour générer statiquement des pages marketing à partir d'un CMS ou d'une section blog du site.

L'utilisation de getInitialProps vous activerait dans SSR dans ce cas.

Next.js a actuellement une commande next export , qui rend l'application entiĂšrement SSG, perdant la nature hybride de Next.js.

Si vous utilisez next export avec getInitialProps , un autre problÚme apparaßt. getInitialProps est appelé au moment de la construction (ce qui est génial), mais ensuite, lorsque vous utilisez next/link pour vous déplacer entre les pages, getInitialProps est appelé cÎté client, au lieu d'utiliser le next export résultat.

Cela signifie également que la source de données (point de terminaison CMS / API) est appelée directement sur les transitions cÎté client, si votre source de données est en panne, les transitions cÎté client sont interrompues lors du déplacement entre les pages.

Nous avons collaboré avec de gros utilisateurs de SSG et next export dans Next.js comme HashiCorp (merci @jescalan) et avons étudié en détail les bonnes contraintes pour introduire deux nouvelles méthodes de récupération de données : getStaticProps et getServerSideProps . Mais aussi un moyen de fournir des paramÚtres pour générer statiquement des pages statiques pour les routes dynamiques : getStaticPaths (remplacement de exportPathMap c'est-à-dire par page).

Ces nouvelles méthodes présentent de nombreux avantages par rapport au modÚle getInitialProps car il existe une distinction claire entre ce qui deviendra SSG vs SSR.

  • getStaticProps marque la page Ă  gĂ©nĂ©rer statiquement au moment de la construction (lors de l'exĂ©cution de next build )
  • getStaticPaths permet de renvoyer une liste de paramĂštres Ă  gĂ©nĂ©rer au moment de la construction pour les routes dynamiques
  • getServerSideProps marque la page Ă  rendre cĂŽtĂ© serveur Ă  chaque requĂȘte et est le plus similaire au comportement actuel de getInitialProps lors de l'utilisation d'un serveur.

SĂ©parer ces mĂ©thodes nous permet Ă©galement de fournir l'objet de contexte correct qui peut ĂȘtre tapĂ© Ă  l'aide de TypeScript. Lorsque vous optez pour une stratĂ©gie de rendu spĂ©cifique, vous obtenez les valeurs correctes, actuellement avec getInitialProps vous devez deviner ce qui est disponible sur SSG vs SSR lors de l'utilisation de TypeScript.

De plus, en rendant ces méthodes explicites, cela nous permettra de documenter plus clairement les différents compromis.

Mise en Ɠuvre

Notez que toutes ces mĂ©thodes sont de niveau supĂ©rieur sur le fichier de composant de page et ne peuvent pas ĂȘtre imbriquĂ©es, comme getInitialProps .

getStaticProps

L'utilisation de getStaticProps signifie que la page sera rendue statiquement au moment de la construction (SSG).

Cette nouvelle méthode vous permettra de récupérer les données d'une page qui sera générée statiquement dans un fichier .html au next build temps.

Next.js générera également automatiquement un fichier JSON contenant le résultat de getStaticProps à next build . Ceci est utilisé pour le routage cÎté client.

Lors du routage cÎté client via next/link ou next/router , Next.js récupÚre ce fichier JSON pour obtenir les accessoires nécessaires au rendu de la page cÎté client.

Les propriĂ©tĂ©s sont renvoyĂ©es sous une clĂ© props afin que d'autres options puissent ĂȘtre introduites Ă  l'avenir.

// 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: {}
  };
}

Le context contiendra :

  • params - Les paramĂštres lors d'un itinĂ©raire dynamique.

getStaticPaths

Il s'agit d'une extension de l'utilisation de getStaticProps pour les routes dynamiques.

getStaticPaths remplace le besoin d'avoir un exportPathMap et fonctionne par page.

Étant donnĂ© que vous souhaiterez peut-ĂȘtre gĂ©nĂ©rer de maniĂšre statique une liste d'URL qui ont un paramĂštre dynamique, comme dans l'exemple ci-dessous un slug . Next.js fournira une mĂ©thode getStaticPaths qui permet de renvoyer une liste d'urls. Comme il s'agit d'une mĂ©thode async , vous pouvez Ă©galement rĂ©cupĂ©rer cette liste Ă  partir d'une source de donnĂ©es comme votre CMS.

// 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" } }
    ]
  };
}

Se retirer

Dans de nombreux cas, vous ne souhaiterez peut-ĂȘtre pas prĂ©-afficher chaque route possible dans votre application au moment de la construction (par exemple si vous avez des millions de produits). Pour cette raison, Next.js gĂ©nĂ©rera automatiquement une page fallback qui est un rendu de la page sans donnĂ©es (afin qu'un Ă©tat de chargement puisse ĂȘtre affichĂ©) lorsque la page n'a pas encore Ă©tĂ© gĂ©nĂ©rĂ©e.

Le comportement exact du service sera :

  • Demande entrante

    • Next.js vĂ©rifie si le chemin a Ă©tĂ© gĂ©nĂ©rĂ© au moment de la construction

    • Si le chemin a Ă©tĂ© gĂ©nĂ©rĂ©



      • servir directement



    • Si le chemin n'a pas Ă©tĂ© gĂ©nĂ©rĂ©



      • Servir le repli


      • Next.js rend la page (avec les donnĂ©es) en arriĂšre-plan et l'ajoute Ă  la liste des pages gĂ©nĂ©rĂ©es


      • Une demande ultĂ©rieure au mĂȘme chemin servira la page gĂ©nĂ©rĂ©e


      • Cela garantit que les utilisateurs ont toujours une expĂ©rience rapide et n'ont jamais de TTFB lent du rendu du serveur tout en prĂ©servant les constructions rapides et les propriĂ©tĂ©s de gĂ©nĂ©ration statique



Au cas oĂč vous voudriez que les chemins qui n'ont pas Ă©tĂ© gĂ©nĂ©rĂ©s au moment de la construction aboutissent Ă  un 404, cela est Ă©galement possible en retournant fallback: false partir de 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

Lorsque vous utilisez getServerSideProps , la page n'est pas générée de maniÚre statique (SSG) et est restituée à la demande à chaque demande au serveur (SSR).

Next.js exposera également automatiquement un point de terminaison d'API qui renvoie le résultat de l'appel de getServerSideProps . Ceci est utilisé pour le routage cÎté client.

Lors du routage cÎté client via next/link ou next/router , Next.js récupÚre ce point de terminaison d'API exposé pour obtenir les données JSON qui sont transformées en accessoires nécessaires au rendu de la page cÎté client.

Cette méthode est la plus similaire à l'actuelle getInitialProps , la principale différence étant que getServerSideProps est toujours exécuté cÎté serveur plutÎt que dans le navigateur. Soit sur le rendu cÎté serveur, soit sur l'API fetch lors du routage cÎté client.

De la mĂȘme maniĂšre que getStaticProps les propriĂ©tĂ©s sont renvoyĂ©es sous une clĂ© props .

// 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: {}
  };
}

Le context contiendra :

  • params - Les paramĂštres sur une route dynamique
  • req - L'objet de requĂȘte HTTP
  • res - L'objet de rĂ©ponse HTTP
  • query - La chaĂźne de requĂȘte (pas tout Ă  fait sĂ»r de celle-ci, mais probablement nĂ©cessaire)

RĂ©digĂ© par @Timer , @ijjk , @lfades. Collaboration avec @rauchg , @jescalan et autres 🚀

Commentaire le plus utile

La prise en charge de la génération de site statique (SSG) de nouvelle génération est désormais stable dans Next.js 9.3 !

Cette version inclut également la prise en charge du "Mode Aperçu", ou la possibilité de contourner la page statiquement pré-rendue et de rendre la page à la demande pour les utilisateurs autorisés .

Vous pouvez en savoir plus Ă  ce sujet dans notre article de blog . Si vous ĂȘtes plus pratique, plongez directement dans nos docs !

Tous les 250 commentaires

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: {}
  };
}

Je suis intĂ©ressĂ© de voir dans quelles circonstances nous aurions besoin de renvoyer des donnĂ©es supplĂ©mentaires autres que celles pouvant ĂȘtre contenues dans props . J'ai trouvĂ© l'explication en ligne "pour contrĂŽler davantage le comportement par page" un peu vague.

Ça a l'air trĂšs intĂ©ressant ! Est-ce qu'il remplacerait getInitialProps ou Ă  cĂŽté ? Par exemple, pour notre cas d'utilisation, l'API de rĂ©cupĂ©ration de donnĂ©es est un service public. Ainsi, sur la navigation cĂŽtĂ© client, nous nous attendons Ă  ce que le client appelle directement la couche API, alors que sur SSR, le serveur l'appelle. À l'avenir, ce cas d'utilisation continuerait-il Ă  ĂȘtre rĂ©solu par la mĂ©thode prĂ©cĂ©dente ?

Je suis intĂ©ressĂ© de voir dans quelles circonstances nous aurions besoin de renvoyer des donnĂ©es supplĂ©mentaires autres que celles pouvant ĂȘtre contenues dans props . J'ai trouvĂ© l'explication en ligne "pour contrĂŽler davantage le comportement par page" un peu vague.

Il s'agit plus de pérenniser la méthode afin qu'elle nous permette de l'étendre ultérieurement si nécessaire.

Ça a l'air trĂšs intĂ©ressant ! Est-ce qu'il remplacerait getInitialProps ou Ă  cĂŽté ? Par exemple, pour notre cas d'utilisation, l'API de rĂ©cupĂ©ration de donnĂ©es est un service public. Ainsi, sur la navigation cĂŽtĂ© client, nous nous attendons Ă  ce que le client appelle directement la couche API, alors que sur SSR, le serveur l'appelle. À l'avenir, ce cas d'utilisation continuerait-il Ă  ĂȘtre rĂ©solu par la mĂ©thode prĂ©cĂ©dente ?

En gĂ©nĂ©ral, ce comportement prĂ©sente certains inconvĂ©nients, par exemple les rĂ©cupĂ©rations en cascade qui peuvent ĂȘtre lentes dans certaines rĂ©gions du monde. L'approche getServerProps permet de mettre en cache la rĂ©ponse plus efficacement.

Cela a l'air vraiment intéressant ! Idée sympa !

J'ai des inquiétudes concernant le déploiement cependant...

Imaginons que j'héberge sur Now.
Pour le premier déploiement, il est évident que l'ensemble des applications est construit sur le déploiement.

Ensuite, je modifie du contenu dans le CMS et je cherche à déclencher la reconstruction des pages SSG uniquement, mais le code de l'application n'a pas changé.

Immédiatement l'alarme se déclenche, que dans ce cas si je déclenche le build, il y a deux solutions possibles :

1) Rien n'est reconstruit, car tout est mis en cache - aucun code n'a changé et blabla.
2) Je l'ai --force , et maintenant "tout" est reconstruit, mais je n'avais besoin que des pages SSG Ă  reconstruire.

_Ce ne sont que des hypothĂšses, car cela dĂ©pend des systĂšmes de construction eux-mĂȘmes - Ă  quel point sont-ils conscients de Next_

Cela affecterait probablement toute autre solution d'hébergement.

Next lui-mĂȘme a un .next/cache ... comment cela fonctionnerait-il?

@joltmode c'est fondamentalement le cas pour chaque générateur de site statique actuellement. .next/cache est conservé entre les déploiements sur Now et réutilisé. Gardez à l'esprit que vous utilisez probablement actuellement getInitialProps pour ce cas avec la mise en cache (potentiellement https://zeit.co/blog/serverless-pre-rendering), qui rend dynamiquement une fonction sans serveur puis se met en cache sur notre CDN, ce Le comportement est toujours tout à fait correct et continuera de fonctionner si vous utilisez getServerProps .

Vraiment génial, s'intégrerait bien dans la façon dont nous utilisons Next pour les projets clients et supprimerait le code passe-partout que nous copions.

Une chose Ă  considĂ©rer est le nom de getStaticProps et getServerProps, s'ils renvoient un { props } et d'autres options potentielles Ă  l'avenir, les *Props ne seraient-ils pas dĂ©routants ? Peut-ĂȘtre que getStaticConfiguration, getStaticSetup, getStaticOptions seraient plus gĂ©nĂ©riques ?

@kibs les valeurs de retour seraient toujours liées à la façon dont les accessoires sont gérés. Donc, le nom est bien imo.

C'est tout simplement gĂ©nial ! Cela rĂ©sout tous les cas d'utilisation et besoins que j'ai eu rĂ©cemment ou auxquels je pourrais penser lors du dĂ©veloppement d'applications Web privĂ©es et professionnelles. Vous venez de m'empĂȘcher de dĂ©marrer mon propre gĂ©nĂ©rateur de site hybride, merci !

Je peux également comprendre que les nouvelles méthodes sont meilleures que les précédentes getInitialProps() et exportPathMap() , ce qui m'a semblé un peu déroutant au début lorsque j'ai commencé à utiliser Next.js et que j'ai creusé dans SSR / SSG. L'approche par page est également plus logique pour moi.

J'ai hùte d'essayer ça !

Juste une note : dans le dernier exemple, je pense qu'il manque un paramĂštre getServerProps() context .

Juste une remarque : dans le dernier exemple, je pense qu'il manque un paramĂštre de contexte Ă  getServerProps().

Fixé!

Cela sonne bien ! Je me demande juste du point de vue d'un utilisateur TypeScript si avoir getStaticProps , getStaticPaths et getServerProps comme mĂ©thodes statiques sur le composant de page (comme getInitialProps pour le moment) ĂȘtre plus facile Ă  saisir/utiliser correctement.

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 le problÚme avec cette approche est qu'il devient beaucoup plus difficile de secouer les arbres (lire: presque impossible). Ce qui signifierait qu'un code inutile serait envoyé au navigateur.

@timneutkens bon point 
 mais alors un fichier sĂ©parĂ© n'aurait-il pas encore plus de sens ? Ou est-ce que quelque chose comme cet arbre _fiable_ est Ă©branlable ?

// 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, nous pouvons le secouer de maniÚre fiable, mais nous discutons également toujours d'un fichier séparé. Personnellement, je préfÚre l'approche du fichier unique.

Ça a l'air trĂšs intĂ©ressant ! Est-ce qu'il remplacerait getInitialProps ou Ă  cĂŽté ? Par exemple, pour notre cas d'utilisation, l'API de rĂ©cupĂ©ration de donnĂ©es est un service public. Ainsi, sur la navigation cĂŽtĂ© client, nous nous attendons Ă  ce que le client appelle directement la couche API, alors que sur SSR, le serveur l'appelle. À l'avenir, ce cas d'utilisation continuerait-il Ă  ĂȘtre rĂ©solu par la mĂ©thode prĂ©cĂ©dente ?

En gĂ©nĂ©ral, ce comportement prĂ©sente certains inconvĂ©nients, par exemple les rĂ©cupĂ©rations en cascade qui peuvent ĂȘtre lentes dans certaines rĂ©gions du monde. L'approche getServerProps permet de mettre en cache la rĂ©ponse plus efficacement.

Bien sĂ»r, mais je parle d'Ă©viter du tout le RTT au serveur de rĂ©action. ConsidĂ©rons le cas oĂč la sortie SSR du serveur est mise en cache sur le proxy du serveur CDN/cache. Ajoutez Ă  cela la rĂ©cupĂ©ration de donnĂ©es pour la navigation client appelant directement une couche API diffĂ©rente (commune au Web / aux applications / Ă  tous les clients), cela signifie que la couche serveur Next.js n'a pas besoin d'ĂȘtre mise Ă  l'Ă©chelle autant dans un scĂ©nario Ă  fort trafic.

Je comprends votre point de récupération en cascade, mais donner aux consommateurs la possibilité de traiter le serveur suivant comme une couche SSR par rapport à une source de données permettrait de bien meilleures configurations de mise à l'échelle.

Ça a l'air trĂšs intĂ©ressant ! Est-ce qu'il remplacerait getInitialProps ou Ă  cĂŽté ? Par exemple, pour notre cas d'utilisation, l'API de rĂ©cupĂ©ration de donnĂ©es est un service public. Ainsi, sur la navigation cĂŽtĂ© client, nous nous attendons Ă  ce que le client appelle directement la couche API, alors que sur SSR, le serveur l'appelle. À l'avenir, ce cas d'utilisation continuerait-il Ă  ĂȘtre rĂ©solu par la mĂ©thode prĂ©cĂ©dente ?

En gĂ©nĂ©ral, ce comportement prĂ©sente certains inconvĂ©nients, par exemple les rĂ©cupĂ©rations en cascade qui peuvent ĂȘtre lentes dans certaines rĂ©gions du monde. L'approche getServerProps permet de mettre en cache la rĂ©ponse plus efficacement.

Bien sĂ»r, mais je parle d'Ă©viter du tout le RTT au serveur de rĂ©action. ConsidĂ©rons le cas oĂč la sortie SSR du serveur est mise en cache sur le proxy du serveur CDN/cache. Ajoutez Ă  cela la rĂ©cupĂ©ration de donnĂ©es pour la navigation client appelant directement une couche API diffĂ©rente (commune au Web / aux applications / Ă  tous les clients), cela signifie que la couche serveur Next.js n'a pas besoin d'ĂȘtre mise Ă  l'Ă©chelle autant dans un scĂ©nario Ă  fort trafic.

Je comprends votre point de récupération en cascade, mais donner aux consommateurs la possibilité de traiter le serveur suivant comme une couche SSR par rapport à une source de données permettrait de bien meilleures configurations de mise à l'échelle.

Je pense que vous ne comprenez pas que ce nouveau comportement signifie que vous pouvez réellement mettre en cache les résultats complets sur un CDN étant donné que le CDN prend en charge les réponses dynamiques. Cela n'était auparavant pas possible de maniÚre fiable avec getInitialProps.

@timneutkens J'ai joué avec Canary, en essayant de porter du code babel-plugin-preval vers getStaticProps . Je rencontre un problÚme avec fs .

J'essaie de lire les fichiers .md de mon répertoire ./pages/blog/ et de les parcourir pour pouvoir créer une page d'index de blog avec tous mes articles

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;

Ce code conduit Ă  cette erreur :

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

IIRC de Razzle, cette erreur est liée aux stubs du systÚme de fichiers de webpack (ou à leur absence). Je pense que j'ai déjà résolu ce problÚme avec Razzle en l'ajoutant à la configuration du pack Web.

node: {
  fs: "empty";
}

J'ai essayĂ© next.config.js, mais l'erreur disparaĂźt. Il semble cependant que fs / fs-extra ne fonctionne pas rĂ©ellement, ou cela fonctionne et peut-ĂȘtre que les chemins ne fonctionnent pas (pas clair pour moi). Des idĂ©es lĂ -dessus ?

Mon autre question, plus gĂ©nĂ©ralement, est de savoir quelles seront, selon vous, les meilleures pratiques pour utiliser import vs. require dans getStaticProps . Si je ne me trompe pas, mon extrait ci-dessus tentera d'importer fs-extra dans React de maniĂšre isomorphe ??. Serait-il donc prĂ©fĂ©rable de changer l'import en une requĂȘte en ligne comme celle-ci ?

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 } }; };

Je pense que vous ne comprenez pas que ce nouveau comportement signifie que vous pouvez réellement mettre en cache les résultats complets sur un CDN étant donné que le CDN prend en charge les réponses dynamiques. Cela n'était auparavant pas possible de maniÚre fiable avec getInitialProps.

Ah, je pense avoir compris ce que tu veux dire. Cela signifierait-il que getServerProps sur la premiĂšre gĂ©nĂ©ration de SSR crĂ©erait un point de terminaison unique, dans un hachage adressable par le contenu, peut-ĂȘtre dans l'URL, que nous pourrions ensuite mettre en cache sur le CDN ? Le seul inconvĂ©nient serait que ledit cache ne serait pas partageable entre les applications non Next (android / ios) et les applications Next. De plus, avec une source de donnĂ©es externe, les directives de contrĂŽle du cache sont en amont, mais ici, puisque Next assumerait la responsabilitĂ© de servir les donnĂ©es, nous avons besoin d'API ou d'accessoires pour spĂ©cifier ceux des points de terminaison de donnĂ©es gĂ©nĂ©rĂ©s.

@jaredpalmer Je suppose que https://github.com/zeit/next.js/issues/9524#issuecomment -558628066 (y compris ma préoccupation concernant la fiabilité de l'arbre à secouer ) serait résolu en ayant un fichier séparé qui serait compilé complÚtement séparément de code de groupe client ? Par exemple

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

or:

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

@jaredpalmer tree

Comme toujours, merci pour tout ce que vous faites. Next.js a été un plaisir absolu de travailler avec, et comme je l'ai déjà dit, à peu prÚs chaque version de fonctionnalité nous permet de _réduire_ la taille des bases de code que je gÚre. C'est incroyable.

Il est difficile de critiquer cette RFC car, telle qu'elle est Ă©crite, elle est immĂ©diatement utile pour BEAUCOUP d'applications. Cependant, je veux aborder une ligne avec laquelle je ne suis pas sĂ»r d'ĂȘtre d'accord :

" getStaticPaths remplace le besoin d'avoir un exportPathMap et fonctionne par page."

Dans certaines applications, il est soit peu pratique, soit impossible de connaĂźtre les routes au moment de la construction. Quelques exemples seraient :

  • Pages de profil utilisateur
  • Pages de produits (pour les entreprises dont l'inventaire Ă©volue rapidement)
  • Pages de dĂ©tails de la commande client

Les routes pour des pages comme celle-ci seront probablement sous la forme /entity-name/entity-id et les routes dynamiques de Next fonctionnent trÚs bien puisque vous pouvez faire des choses comme router.push('/customers/[customerId]', '/customers/baer') . Il y a encore un hic. Si vous prévoyez de servir ces fichiers de maniÚre statique avec quelque chose comme Serve, Netlify, NGINX, etc., vous devrez générer un ensemble de redirections afin que les utilisateurs n'obtiennent pas un 404 lors de l'actualisation de la page et, pour ce faire, besoin de exportPathMap .

Ce qui suit est copié, presque tel quel, à partir d'une base de code sur laquelle je travaille réguliÚrement :

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;
}

Je comprends que cette RFC ne dĂ©sapprouve ni ne supprime aucune API et je reconnais Ă©galement qu'il est possible de crĂ©er ces redirections en parcourant le rĂ©pertoire de construction, donc mĂȘme si elle Ă©tait dĂ©sapprouvĂ©e, j'ai une belle trappe d'Ă©vasion. Mais cela ne "supprime pas tout Ă  fait le besoin de getStaticPaths ."

Encore une fois, merci pour votre attention dans la façon dont vous gérez ce projet

Les getStaticProps / getStaticPaths et getServerProps s'excluent-ils mutuellement ? c'est-Ă -dire serait-il possible d'avoir une piĂšce prĂ©-rendue et une piĂšce dynamique en mĂȘme temps ?

Oui, ils le sont car l'un est la génération statique et l'autre le rendu cÎté serveur.

Cela corrige l'une des grandes choses qui me manquent de Gatsby avant la migration vers Next :

Nous avons un fichier JSON monolithique (100 ko) dont nous extrayons les données pour rendre nos pages qui ne changent jamais. Dans Gatsby, nous avons chargé le fichier JSON dans le schéma GraphQL et l'avons interrogé, en ne saisissant que les données dont nous avions besoin pour afficher une page donnée. Avec Next, le moyen le plus simple/le plus propre que nous ayons trouvé est import monolith from './monolith.json' , ce qui nécessite que l'utilisateur télécharge l'intégralité du fichier JSON.

Cette RFC 100% aborde ce cas d'utilisation et rapproche Next un peu plus d'ĂȘtre Ă  Ă©galitĂ© avec Gatsby dans les domaines oĂč Gatsby brille (Ă©videmment, Gatsby ne peut pas faire de SSR d'exĂ©cution, donc je ne parle que de rendus statiques Ă  la construction)

@timneutkens , merci pour le RFC !

J'ai un cas d'utilisation pour Next.js dont j'ai récemment discuté avec @rauchg.

Next.js offre un DX trÚs fluide et quelques valeurs par défaut raisonnables. Je suis donc intéressé par l'utilisation de Next.js pour une application de rendu cÎté client uniquement, une application Smart TV.

Les applications Smart TV sont des applications Web presque classiques exécutées par le moteur de navigation de la télévision :

  1. L'application est regroupée dans un ensemble : styles, scripts, images, _index.html_, certificats et fichier de configuration TV.
  2. L'ensemble est soumis pour examen Ă  la boutique d'applications de la plate-forme.
  3. Le bundle est ensuite installé à partir du magasin en tant qu'application et est exécuté par l'utilisateur.

Le fait est que le bundle est hĂ©bergĂ© de maniĂšre statique par l'appareil TV lui-mĂȘme et n'est pas chargĂ© depuis le serveur. Ainsi, aucune option SSR n'est possible (Node.js n'est pas exposĂ© aux dĂ©veloppeurs Ă  ces fins). Mais l'application elle-mĂȘme est dynamique (par exemple, Netflix).

Nous devons donc exécuter un SPA hébergé par un serveur Web statique.

D'aprÚs ce que je comprends, la désactivation de getServerProps (ou getInitialProps ) aidera complÚtement à éviter la SSR. Mais que se passe-t-il avec le rendu dynamique sur le client ? Et qu'en est-il du routage dans ce cas ? Selon cette RFC, le problÚme n'a pas encore été résolu. @timneutkens , pourriez-vous, s'il vous plaßt, suggérer le meilleur moyen d'activer le rendu cÎté client uniquement dans Next.js ? Et s'il convient à Next.js en premier lieu ? Merci!

PS Je peux créer un problÚme pour ce cas d'utilisation si vous pensez qu'il est préférable d'en discuter séparément.

@gruchetsky pouvez-vous crĂ©er un problĂšme diffĂ©rent. C'est une question complĂštement diffĂ©rente de ce qui est discutĂ© dans le RFC 👍

@timneutkens La promesse de cette RFC est l'une des choses qui m'ont vraiment enthousiasmé par Next ! Juste pour clarifier cependant, getInitialProps existerait toujours aussi, n'est-ce pas ?

Correct @outdooricon -- getInitialProps restera dans un avenir prévisible.

Selon la RFC :

Cette RFC traite exclusivement des ajouts d'API. Toutes les nouvelles fonctionnalitĂ©s sont entiĂšrement rĂ©trocompatibles et peuvent ĂȘtre progressivement adoptĂ©es. Cette RFC n'introduit aucune dĂ©prĂ©ciation.

Super RFC, super excité pour ça!

J'ai pensĂ© au getServerProps par rapport Ă  un cas d'utilisation spĂ©cifique, en mettant les rĂ©sultats dans un cache. Étant donnĂ© que cela est transformĂ© en un point de terminaison d'API et que le rĂ©sultat est fourni au composant en tant qu'accessoires, existe-t-il un moyen prescrit de placer le rĂ©sultat dans un cache externe tel que Redux, GraphQL-caches, etc., etc. cĂŽtĂ© client ?

Si je comprends bien getInitialProps , puisqu'il est statique et asynchrone, Next a la possibilitĂ© d'attendre qu'il se termine avant de rendre le composant une premiĂšre fois. Cela nous permet de mettre les choses dans un cache externe lĂ -bas. Ce ne sera pas le cas avec getServerProps car il s'exĂ©cute sur le serveur, et mettre les choses dans un cache dans le cycle de vie du composant semble signifier que nous devons avoir un rendu oĂč les donnĂ©es ne sont pas encore disponibles dans le cache , mĂȘme s'il est disponible dans les accessoires ?

Cela peut ĂȘtre intentionnel bien sĂ»r et il se peut que je manque une approche, mais j'ai pensĂ© que je demanderais si c'est quelque chose qui a Ă©tĂ© envisagé ?

Edit : Je suppose que cela s'applique également à getStaticProps . ??

Peut-ĂȘtre que je l'ai ratĂ© quelque part, mais comment gĂ©rons-nous les situations oĂč le contenu est mis en cache, mais il est mis Ă  jour dans la base de donnĂ©es ou un nouveau billet de blog est créé ? Il est nĂ©cessaire de faire une nouvelle construction automatiquement ? Je suppose.

Tout d'abord! Excellente proposition, c'est une amélioration massive par rapport à exportPathMaps dans le cas d'utilisation de la plupart des gens. C'est vraiment apprécié. Cela dit, j'ai du mal à comprendre comment pourrions-nous le faire fonctionner avec l'internationalisation des routes.

Y a-t-il des suggestions sur la façon de gérer les routes préfixées i18n ? Mon cas d'utilisation spécifique nécessite de créer quelques milliers de pages avec différents préfixes et URL de pays-lang.

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

Il semble que getStaticPaths sera vraiment utile lorsque le préfixe de l'url est bien connu, comme dans votre exemple (en utilisant /blog/[id].js ). Mais à quoi pensez-vous qu'une implémentation getStaticPaths ressemblera si elle doit générer des chemins au niveau racine, avec à la fois un préfixe dynamique (country-lang) et un chemin dynamique ?

@reaktivo pages/[lang]/blog/[id].js -> dans getStaticPaths fournit toutes les URL Ă  rendre statiquement.

@timneutkens Une idée de quand cela sera disponible / testable ?

En général, nous ne donnons pas d'ETA car nous testons de maniÚre approfondie les fonctionnalités par rapport aux applications de production pour nous assurer que la solution est la bonne.

Ces améliorations me feront totalement déprécier mon projet phénomique "pas que maintenu" (réagir ssg que personne n'utilise sauf moi). Génial de voir Next.js ajouter ces piÚces manquantes !

Je voudrais clarifier un doute. Considérant l'utilisation d'un CMS comme wordpress. Si je comprends bien, avec la méthode getStaticPaths, je récupÚrerais tous les messages et transmettrais une liste comme :

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

Le slug de chaque publication serait utilisé dans la méthode getStaticProps pour récupérer le contenu.
Cela se produirait dans npm build.
Ma question concerne les nouveaux messages qui seront ajoutés aprÚs la construction.
La méthode getStaticProps serait-elle utilisée pour récupérer ce nouveau message par limace ?
Ce nouveau message aura-t-il un fichier .html comme celui de la version précédente ?
J'aime travailler avec le prochain et dans plusieurs projets que j'ai, ce serait trĂšs bien.

Rien de directement lié, mais le support n'est pas en mesure de me donner une réponse qui corresponde à ma question.

Ce que vous suggĂ©rez ici pourrait ĂȘtre la solution, mais en attendant, je ne parviens pas Ă  faire en sorte que nextJS crĂ©e un JAMSTACK basĂ© sur les modifications des webhooks.

si j'avais getInitialProps, je serais rendu par le serveur.
Si je ne le fais pas, je suis juste CDNisé, mais sans pré-rendu n'est-ce pas ? Et la page sera sans contenu tant que XHR ne sera pas revenu (bye-bye SEO)

Avez-vous un exemple en cours d'exécution avec maintenant de Jamstack avec nextJS et nous pourrions le faire sur netlify.

Merci,
Andréas

HĂ© @ScreamZ - ce changement est, je pense, ce qui permet Ă  un site entiĂšrement statique d'ĂȘtre construit avec nextjs. Nous avons pu compiler un site nextjs en statique en utilisant next export pendant longtemps, mais il rĂ©cupĂšrerait toujours les donnĂ©es sur les transitions de route cĂŽtĂ© client en utilisant getInitialProps . Avec la possibilitĂ© d'utiliser getStaticProps , vous pouvez exĂ©cuter des transitions cĂŽtĂ© client sans qu'aucune donnĂ©e supplĂ©mentaire ne soit rĂ©cupĂ©rĂ©e - toutes les donnĂ©es rĂ©cupĂ©rĂ©es dans getStaticProps sont rĂ©cupĂ©rĂ©es une fois, au moment de la construction, et ne sont pas mises Ă  jour sur votre site en direct Ă  moins que vous ne reconstruisiez Ă  nouveau. Il s'agit de l'architecture classique des sites statiques basĂ©s sur les donnĂ©es, reliez votre source de donnĂ©es Ă  votre hĂ©bergeur via un webhook et lorsque la source de donnĂ©es change, vous dites Ă  l'hĂ©bergeur de reconstruire votre site.

Il existe de nombreux exemples existants de sites Web nextjs entiÚrement statiques, et il est trivial d'exécuter un site nextjs sur netlify. Le site Web de mon entreprise fonctionne actuellement sur nextjs et est hébergé par netlify, j'espÚre que cela sert de bon exemple.

Il convient de noter que le service d'hĂ©bergement de zeit mĂ©rite Ă©galement d'ĂȘtre fortement pris en compte. Le prix est assez similaire, et leur intĂ©gration avec les sites nextjs est incomparable - vous n'avez mĂȘme pas besoin de configurer quoi que ce soit du tout, il vous suffit de lier github et l'hĂ©bergement de zeit reconnaĂźtra que vous exĂ©cutez nextjs et configurez et dĂ©ployez automatiquement tout.

Ce n'est en aucun cas une publicité, je ne travaille pas pour zeit, juste une véritable approbation. Vous pouvez tout à fait le faire fonctionner avec netlify, et j'en ai personnellement pour plusieurs sites comme preuve. Mais vous devrez bien comprendre le fonctionnement de nextjs et vous assurer que tout est correctement configuré pour que tout fonctionne correctement sur netlify. Si vous recherchez l'hébergement le plus simple et le plus infaillible pour un site nextjs, j'essayerais l'hébergement zeit.

@jescalan Merci pour ce super partage đŸ™đŸ»

Je n'ai aucun problÚme à utiliser NextJS avec netlify, car vous pouvez utiliser Publish directory pour spécifier le dossier out . Mais sur zeit Maintenant, il n'y a aucun moyen de dire, s'il vous plaßt, n'utilisez pas le SSR mais optez pour le statique avec next export .

@ScreamZ c'est en quelque sorte vrai, mais cela dĂ©pend de la façon dont vous dĂ©finissez exactement un site "complĂštement statique". Si vous utilisez getStaticProps pour toutes vos pages avec le service d'hĂ©bergement de zeit, ce que vous obtiendrez est effectivement Ă©gal Ă  un site statique, mĂȘme s'il n'exĂ©cute pas next export , puisque toutes les pages avec getStaticProps sont construits uniquement lorsque le site est dĂ©ployĂ©, et sont servis directement Ă  partir du CDN aprĂšs cela.

La principale diffĂ©rence est que, pour autant que je sache, il n'existe aucun moyen de forcer toutes les pages Ă  ĂȘtre statiques sur l'hĂ©bergement de zeit (modifier : zeit l'a rĂ©cemment modifiĂ© afin que tout site avec une configuration contenant exportPathMap s'exĂ©cute un site entiĂšrement statique, donc ce n'est plus vrai). Les pages avec getStaticProps se comportent exactement de la mĂȘme maniĂšre que les pages gĂ©nĂ©rĂ©es par next export -- une seule copie statique de la page est servie directement depuis le CDN Ă  chaque appel. Mais vous pouvez Ă©galement exĂ©cuter certaines pages avec getServerProps ou getInitialProps et elles se comporteraient comme des pages rendues par le serveur. Personnellement, je vois cela comme un avantage - s'il y a un besoin pour une route SSR, vous pouvez simplement utiliser une mĂ©thode de rĂ©cupĂ©ration de donnĂ©es diffĂ©rente et cette seule route est maintenant SSR, tandis que toutes vos autres routes peuvent rester statiques.

@jescalan Merci,

Il suffit donc d'attendre que cela soit mis en Ɠuvre, en attendant, je vais utiliser netlify pour la statique

Y a-t-il une histoire autour de la configuration SSG ? Plus précisément, nous aimerions utiliser des artefacts de construction partagés mais exécuter next export avec différentes configurations pour QA/prod. Ces valeurs de configuration ne seraient lues que dans getStaticProps . Cela utiliserait-il le serverRuntimeConfig ou publicRuntimeConfig ou process.env directement ?

@ScreamZ @jescalan J'ai obtenu le support zéro-config next export sur Now aujourd'hui avec @Timer (il mérite tous les crédits). Tu peux faire:

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

Et cela fonctionnera automatiquement.

Dis moi comment ça se passe

Ouais, j'Ă©tais le gars qui a demandĂ© le support et ils m'ont dit que cela avait Ă©tĂ© implĂ©mentĂ© pour l'instant 😅 Pour autant que je puisse voir, vous aurez besoin de dĂ©finir une carte d'exportation dans la configuration ?

@ScreamZ non, vous pouvez simplement ajouter next build && next export comme indiqué ci-dessus et cela fonctionnera.

@timneutkens Si je remplace getInitialProps par getServerProps , dois-je toujours ajouter target: 'serverless' au fichier de configuration pour activer Server Pre Rendering ? Merci.

Comment pouvons-nous essayer ceux-ci?

Comment pouvons-nous essayer ceux-ci?

Je suppose que toutes ces mĂ©thodes ont actuellement besoin du prĂ©fixe unstable_ pour ĂȘtre reconnues.

par exemple unstable_getStaticProps

@timneutkens

@ScreamZ @jescalan J'ai obtenu le support zéro-config next export sur Now aujourd'hui avec @Timer (il mérite tous les crédits). Tu peux faire:

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

Et cela fonctionnera automatiquement.

Dis moi comment ça se passe

Mon script de construction fait un peu plus de choses, mais il semble que cela fonctionne comme un charme :

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

En plus c'est super ! C'Ă©tait exactement ce que je cherchais 😅 (Au revoir GatsbyJS, mon framework prĂ©fĂ©rĂ© est maintenant aussi fort que toi !)

Merci beaucoup pour cette réactivité.

J'ai Ă©galement mis Ă  niveau vers 9.1.6 et j'ai vu cela avec surprise
Screenshot 2019-12-21 at 19 25 43

Je pensais que ce fil était un RFC, on dirait qu'il nous est déjà ouvert ahah, n'est-ce pas ?
Cependant, les types Typescript ne sont pas activés dans 9.1.6.

Merde, je suis tellement excité pour ça maintenant! ??

DerniĂšres questions :

  • Si je l'obtiens, getInitialProps sera obsolĂšte Ă  l'avenir ? Ou est-ce toujours pertinent dans certains cas ? Un exemple?
  • next export peut Ă©galement ĂȘtre dĂ©prĂ©ciĂ© en faveur des pages avec getStaticProps et next build seulement ?

Merci pour ce super outil

Si je l'obtiens, getInitialProps sera obsolÚte à l'avenir ? Ou est-ce toujours pertinent dans certains cas ? Un exemple?

Comme indiqué dans la RFC initiale :

Cette RFC traite exclusivement des ajouts d'API. Toutes les nouvelles fonctionnalitĂ©s sont entiĂšrement rĂ©trocompatibles et peuvent ĂȘtre progressivement adoptĂ©es. Cette RFC n'introduit aucune dĂ©prĂ©ciation.

Je pensais que ce fil était un RFC, on dirait qu'il nous est déjà ouvert ahah, n'est-ce pas ?

Ce n'est pas le cas, nous l'essayons sur des applications ZEIT et une partie de la visibilité a déjà atterri (par exemple l'arborescence des pages que vous avez vue).

la prochaine exportation peut Ă©galement ĂȘtre dĂ©prĂ©ciĂ©e en faveur des pages avec getStaticProps et la prochaine gĂ©nĂ©ration uniquement ?

Correct, en général, vous finirez par ne pas utiliser next export . Elle sera conservée pour des raisons de compatibilité descendante, mais en général, vous souhaiterez créer une application hybride car elle vous offre tous les avantages de l'exportation avec la prise en charge d'autres fonctionnalités telles que les routes API et l'option de rendu cÎté serveur pour certaines pages.

Comment pouvons-nous essayer ceux-ci?

Je suppose que toutes ces mĂ©thodes ont actuellement besoin du prĂ©fixe unstable_ pour ĂȘtre reconnues.

par exemple unstable_getStaticProps

Je recommande vivement de ne pas l'utiliser pour le moment, c'est expérimental et peut casser entre les versions.

J'ai donc joué avec cette fonctionnalité et j'ai observé que le fichier JSON contenant les données de la page est toujours récupéré aprÚs avoir accédé à la page SSG à partir d'une autre page.

Prévoyez-vous une optimisation de préchargement pour le fichier JSON ?
Peut-ĂȘtre en le prĂ©chargeant lorsque l'utilisateur est sur le point de naviguer vers la page (c'est-Ă -dire: l'utilisateur survole un lien SSG) ou en le prĂ©chargeant tout comme vous prĂ©chargez d'autres pages js rĂ©fĂ©rencĂ©es Ă  partir d'un composant Link.

J'adore cette fonctionnalité au fait!

Prévoyez-vous une optimisation de préchargement pour le fichier JSON ?

Oui.

Pour ce que ça vaut, je suis tout à fait pour les exportations de ces fonctions plutÎt que pour des fichiers séparés.

Quel est le statut de cette fonctionnalité ? Quels sont ses bloqueurs ?

@mikestopcontinue cette RFC est actuellement fortement testée en interne par notre équipe et quelques partenaires sélectionnés. Vous pouvez opter pour son comportement hautement expérimental en utilisant les préfixes unstable_ , comme mentionné ci-dessus ! ??

Veuillez ne pas migrer les charges de travail de production vers les nouvelles méthodes, car nous pouvons toujours mettre à jour les API de maniÚre incontrÎlable.

Personnellement, je l'utilise pour la gĂ©nĂ©ration de sites statiques de 8 Ă  20K pages (avec la possibilitĂ© d'avoir des requĂȘtes dynamiques sur certaines pages). Cela fonctionne trĂšs bien (sauf pour la limite de 10K fichiers sur Now), la seule chose que je trouve dommage c'est que sans la mĂ©thode getStaticPaths, getStaticProps est appelĂ© Ă  chaque rechargement. Un comportement qui pourrait ĂȘtre bon est que le premier appel crĂ©e le fichier json et que le suivant l'utilise.

Des builds incrémentiels sont-ils prévus ? Ainsi, seul le contenu nouveau/modifié est reconstruit ?

Vous pouvez opter pour son comportement hautement expérimental en utilisant les préfixes unstable_ , comme mentionné ci-dessus !

J'aimerais tester la méthode unstable_getServerProps , mais il semble qu'elle soit ignorée pour le moment, et je ne la trouve nulle part dans le zeit/next.js . N'est-il pas encore implémenté ou est-ce que je le fais simplement mal ?

Des builds incrémentiels sont-ils prévus ? Ainsi, seul le contenu nouveau/modifié est reconstruit ?

L'implémentation a été conçue avec des reconstructions incrémentielles à l'esprit, mais elle n'est pas encore prise en charge (ni couverte dans cette RFC).

Rassurez-vous, l'architecture est prĂȘte et nous explorerons cela une fois que ces fonctionnalitĂ©s seront stables.
C'est pourquoi getStaticProps est défini par page, et pas une seule fois pour l'ensemble de l'application !

J'aimerais tester la méthode unstable_getServerProps, mais il semble qu'elle soit ignorée pour le moment [...]

getServerProps n'est pas encore disponible en avant-premiÚre, désolé !

getServerProps n'est pas encore disponible en avant-premiÚre, désolé !

Merci pour l'information. Je vais certainement regarder ce fil, car quand cela arrivera, j'ai un _bouquet_ de code qui peut ĂȘtre remplacĂ© en renommant une seule fonction ! ??

Veuillez clarifier, je ne suis pas sûr à 100 % si getServerProps / getStaticProps sont actuellement disponibles ou non.

Basé sur ce fil: Non

Mais si c'est le cas, alors je me demande pourquoi mon terminal y a-t-il fait allusion lorsque j'ai exécuté next build s'ils ne sont pas encore disponibles ? Voir le message m'a laissé avec l'hypothÚse de travail initiale que ces méthodes étaient en production, et il m'a fallu un certain temps pour découvrir qu'elles ne l'étaient pas. Je suis juste curieux de connaßtre le raisonnement ou s'il y a quelque chose que j'ai mal compris.

λ  (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)

(sur la prochaine version 9.1.6)

Merci

@stevenjchang ils sont disponibles en utilisant la syntaxe suivante dans pages/**/*.js :

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

Et je devrais Ă©galement ajouter, ils sont merveilleux, mĂȘme s'ils sont encore un peu rugueux sur les bords lors de l'utilisation du serveur de dĂ©veloppement.

bien qu'ils soient encore un peu rugueux sur les bords lors de l'utilisation du serveur de développement.
@mikestopcontinue

Peux tu développer ta pensée à ce propos? Personne d'autre ne nous a donné de commentaires négatifs sur l'expérience du serveur de développement, et nous aimerions le résoudre !

@Timer J'aime vraiment la nouvelle api. Mon principal problÚme pendant le développement est que le json est redemandé à chaque chargement. Cela ralentit les tests, mais cela déforme également l'expérience de l'utilisateur lorsqu'il navigue réellement sur le site.

Par « à chaque chargement », voulez-vous dire le chargement de la page ? Ou reconstruire ? Ou...?

@mmmeff Chaque fois que vous naviguez vers le mĂȘme chemin, il redemande le json. Ainsi, si vous faites des allers-retours entre deux pages, vous passez beaucoup de temps Ă  attendre des donnĂ©es.

@mikestopcontinue c'est le comportement prévu, car les données les plus à jour sont souvent préférables en développement. Serait ouvert à discuter de meilleures heuristiques dans un nouveau numéro !

@timneutkens Cette RFC semble trÚs prometteuse. J'ai quelques questions/préoccupations concernant la sécurité et son fonctionnement exact.

Prenons une analyse de rentabilisation générique qui repose à la fois sur la SSR et la SSG.

Le contexte

Nous souhaitons afficher certaines informations sur un site Web (AKA "app").
Ces informations sont stockées dans un BDD accessible via une API GraphQL.
Certaines de ces informations sont publiques, d'autres privées (c'est-à-dire : e-mails/mot de passe des utilisateurs).

L'application utilise deux étapes :

  • Une Ă©tape de "staging", oĂč le client peut voir les changements en temps rĂ©el dans l'application de staging (il met Ă  jour ces informations via un back-office ou similaire)
  • Une Ă©tape de "production", oĂč le client n'a aucun accĂšs et ne peut rien mettre Ă  jour par lui-mĂȘme. Pour mettre Ă  jour l'application de production, un nouveau dĂ©ploiement doit ĂȘtre effectuĂ©. (ils demandent qu'un nouveau dĂ©ploiement de production soit fait, depuis leur dit back-office)

Dans ce scénario, nous utilisons à la fois SSR et SSG :

  • L'application de mise en scĂšne utilise SSR, car elle rĂ©cupĂšre en temps rĂ©el les donnĂ©es de l'API GraphQL (lors de la crĂ©ation d'une page)
  • L'application de production utilise SSG, car lorsqu'un nouveau dĂ©ploiement est effectuĂ©, elle rĂ©cupĂšre les donnĂ©es de l'API GraphQL et en gĂ©nĂšre des pages statiques (elles sont donc statiques et ne changeront plus, aucune requĂȘte ne sera adressĂ©e Ă  l'API GraphQL au moment de l'exĂ©cution (du moins pas lors du chargement d'une page))

Ce scĂ©nario devrait ĂȘtre suffisamment gĂ©nĂ©rique et devrait ĂȘtre (Ă  mon humble avis) l'un des principaux cas d'utilisation de l'utilisation de SSG.
L'application de production n'est rien de plus qu'un instantané de l'application intermédiaire.

Quelques questions:

  1. Est-ce possible avec ce RFC ? Avoir la mĂȘme application se comportant diffĂ©remment en fonction d'une "Ă©tape" donnĂ©e (production/mise en scĂšne)
  2. Comment les données extraites de l'API GraphQL sont-elles injectées ?

    • Dans la mise en scĂšne, ils sont rĂ©cupĂ©rĂ©s dynamiquement via SSR, ou CSR lorsque l'utilisateur parcourt les pages (et seront disponibles sur le navigateur s'ils sont rĂ©cupĂ©rĂ©s pendant CSR)

    • En production, ils sont rĂ©cupĂ©rĂ©s au moment de la construction, mais alors, sont-ils stockĂ©s dans une variable globale JS et peuvent donc ĂȘtre lus par n'importe qui ? (problĂšme de sĂ©curitĂ©, car nous devons ĂȘtre conscients de ne pas rĂ©cupĂ©rer les donnĂ©es sensibles qui peuvent ĂȘtre mises Ă  disposition sur le navigateur, de la mĂȘme maniĂšre que lors de l'utilisation de la RSE)

  3. Auriez-vous des inquiétudes concernant cette approche avec SSR/SSG mixtes ? (sécurité, performances, maintenabilité, etc.)

Quand comptez-vous le sortir ? Est-ce que ce sera une mise à jour majeure (v10) ou une mise à jour rétrocompatible ?

Hey,

Avez-vous essayé cette solution avec un serveur personnalisé et la faire fonctionner?

Exemple:

// 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 }

Pourquoi getStaticProps ne peut-il pas inclure la chaĂźne de requĂȘte ? J'ai actuellement une page que je dois SSR simplement pour obtenir les paramĂštres de requĂȘte sans re-rendu. L'utilisation du crochet useRouter provoque plusieurs re-rendus, car la requĂȘte est initialement un objet vide. C'est une page qui est utilisĂ©e pour le suivi des conversions, donc Ă©videmment, c'est un non-starter.

@pjaws La RFC mentionne spĂ©cifiquement que getStaticProps est pour la gĂ©nĂ©ration statique. Le HTML statique ne peut pas recevoir de chaĂźne de requĂȘte.

Alors pourquoi peut-il recevoir des paramÚtres d'URL dynamiques ? En quoi est-ce différent ?

Le mardi 14 janvier 2020 Ă  01h30 Tim Neutkens [email protected]
a Ă©crit:

@pjaws https://github.com/pjaws Le RFC qu'il mentionne spécifiquement
getStaticProps est destiné à la génération statique. Le HTML statique ne peut pas recevoir de
chaĂźne de requĂȘte.

-
Vous recevez ceci parce que vous avez été mentionné.
RĂ©pondez directement Ă  cet e-mail, consultez-le sur GitHub
https://github.com/zeit/next.js/issues/9524?email_source=notifications&email_token=AMVRRIQCKDJNF4MPWSLYNV3Q5WA2NA5CNFSM4JRPBEL2YY3PNVWWK3TUL52HS4DFVREXG43VMVBWW63LNMV5WWW2ZLOJK45
ou se désinscrire
https://github.com/notifications/unsubscribe-auth/AMVRRIRJXLYC4MC4U7DH7NDQ5WA2NANCNFSM4JRPBELQ
.

Parce que dans getStaticPaths vous devez retourner les pages qui seront rendues au moment de la construction.

Ces changements semblent trÚs prometteurs, excellent travail comme toujours ! ??

Je m'interroge sur le cas d'utilisation d'avoir getInitialProps dans _app.js pour satisfaire les besoins de donnĂ©es partagĂ©s entre les pages (par exemple, configurer des fournisseurs de contexte). Ai-je bien compris qu'il est impossible d'utiliser getStaticProps de la mĂȘme maniĂšre ? Il n'est possible de le dĂ©finir que dans des pages individuelles ?

Je m'interroge sur le cas d'utilisation d'avoir getInitialProps dans _app.js pour satisfaire les besoins de donnĂ©es partagĂ©s entre les pages (par exemple, configuration de fournisseurs de contexte). Ai-je bien compris qu'il est impossible d'utiliser getStaticProps de la mĂȘme maniĂšre ? Il n'est possible de le dĂ©finir que dans des pages individuelles ?

Correct, au dĂ©part, ce sera juste pour des pages individuelles. Peut-ĂȘtre reconsidĂ©rer plus tard. Le getInitialProps de _app sera toujours appelĂ© lors de l'exportation au format HTML statique afin que vous puissiez passer progressivement Ă  getStaticProps.

salut les gars, une question connexe - comment les actifs seront-ils traitĂ©s ? parce que je vois en ce moment que si j'utilise un CMS sans tĂȘte (mĂȘme wordpress ou graphcms ou autre), l'url de l'actif est utilisĂ©e dans le html statique.

Il y a deux préférences ici - que les liens d'actifs soient utilisés en tant que tels.
Mais plus probablement - téléchargez l'actif, construisez le html (lien vers celui-ci localement), puis superposez un CDN devant. C'est la pratique la plus acceptable.

Cela correspond également trÚs bien à l'utilisation de systÚmes de déploiement comme Netlify - qui disposent d'une infrastructure disponible dans le monde beaucoup, beaucoup plus appropriée que quelque chose comme DatoCMS ou Graphcms. Donc, si j'utilise Netlify comme déploiement, je voudrais que tout soit servi à partir du domaine Netlify et le laisse faire sa magie.

@sandys Si je comprends bien dans https://github.com/zeit/next.js/issues/9054#issuecomment -570427085, vous ĂȘtes censĂ© tĂ©lĂ©charger les actifs, les stocker sous .next/static et crĂ©er un lien vous-mĂȘme en getStaticProps .

Il y a aussi l'idée d'avoir des routes api statiques, mais je ne sais pas exactement comment vous contrÎleriez le comportement de mise en cache du navigateur avec cela.

@Janpot merci pour le lien. Les commentaires semblent indiquer que ce genre de choses doit ĂȘtre autonome.

S'il vous plaĂźt ajouter ma demande d'avoir ceci intĂ©grĂ©. Peut-ĂȘtre que #9054 est plus gĂ©nĂ©rique, mais je pense du point de vue de SSG et c'est EXTRÊMEMENT essentiel.

J'ai oublié de le mentionner, mais le hachage des actifs sera également essentiel pour SSG.

@homoky , Vous n'avez pas réussi à faire fonctionner cela, avez-vous fait des progrÚs entre-temps ?

@homoky , Vous n'avez pas réussi à faire fonctionner cela, avez-vous fait des progrÚs entre-temps ?

Ce n'est pas possible et ce n'est pas non plus prévu : #10071

??

@sandys en fait, la solution est beaucoup plus simple lorsque vous utilisez https://github.com/zeit/next.js/issues/9081 pour ajouter une rĂ©Ă©criture de par exemple /images au CMS. Par exemple sur ZEIT Maintenant, il mettrait dĂ©jĂ  en cache le rĂ©sultat lorsque les en-tĂȘtes corrects sont ajoutĂ©s, pas besoin de tĂ©lĂ©chargement supplĂ©mentaire (coĂ»t Ă©norme lors de la construction).

@timneutkens merci d'avoir répondu.
Pas tout à fait sûr de ce que vous voulez dire. Nous utilisons donc netlify - suggérez-vous que nous gardions les URL du CMS en tant que telles et que nous placions une couche de CDN dessus ?
Je ne sais pas si netlify (cloudfront que nous prévoyons d'utiliser) peut fonctionner de maniÚre transparente avec tous ces services.

Si les images sont téléchargées et intégrées au déploiement, alors tout ce problÚme est considérablement simplifié. Parce que j'ai configuré le CDN pour mettre en cache à partir de l'URL de base (qui, dans mon cas, sera servie à partir de s3).

Je ne sais pas tout Ă  fait si votre solution repose sur moi en utilisant Zeit NOW

Si les images sont téléchargées et intégrées au déploiement, alors tout ce problÚme est considérablement simplifié. Parce que j'ai configuré le CDN pour mettre en cache à partir de l'URL de base (qui, dans mon cas, sera servie à partir de s3).

Cela rend le processus de construction beaucoup plus complexe et 10 fois plus lent, certainement pas plus simple.

Je ne sais pas tout Ă  fait si votre solution repose sur moi en utilisant Zeit NOW

Fonctionne avec tous les proxy dans le monde. Y compris cloudfront.

@timneutkens, nous sommes en fait

Je ne préconise certainement pas que vous l'activiez pour tout le monde. Beaucoup de gens seront heureux de créer des liens profonds vers un CMS. Mais nous gérons un site à fort trafic et c'est certainement quelque chose dont les sites comme nous ont besoin.

Aussi, pardonnez-moi, mais je n'ai pas compris votre solution. comment devrions-nous configurer cela? Je n'ai pas le contrĂŽle sur l'URL qu'un CMS utilise. Par exemple, Datocms commence Ă  servir Ă  partir de www.datocms-assets.com/ . Comment utilisons-nous la solution dans #9081 ?

nous sommes en fait indépendants du temps de processus de construction. peu importe si cela prend plus de temps

Cela peut ĂȘtre vrai pour votre application, mais ce n'est pas le cas pour la majoritĂ© des applications.

mais pour de nombreuses raisons (y compris tous les actifs servis à partir d'une URL de base connue), il serait hautement préférable de l'avoir intégré dans la construction.

Cela n'a vraiment pas besoin d'ĂȘtre comme dit, vous pouvez utiliser une rĂ©Ă©criture qui proxie /images/* Ă  l'url cms, par exemple www.datocms-asset.com/* ou similaire. Et puis il suffit de lier toutes les images en utilisant /images .

Notez que cela commence Ă  sortir du sujet.

@sandys en fait, la solution est beaucoup plus simple lorsque vous utilisez #9081 pour ajouter une rĂ©Ă©criture Ă  partir, par exemple, de /images vers le CMS. Par exemple sur ZEIT Maintenant, il mettrait dĂ©jĂ  en cache le rĂ©sultat lorsque les en-tĂȘtes corrects sont ajoutĂ©s, pas besoin de tĂ©lĂ©chargement supplĂ©mentaire (coĂ»t Ă©norme lors de la construction).

@timneutkens Juste pour que les choses

  1. optimiser les images
  2. hacher les images et les servir sous ce hachage
  3. fournir une carte de l'url de l'image Ă  l'url de l'image hachĂ©e qui peut ĂȘtre tĂ©lĂ©chargĂ©e en getStaticProps pour remapper les URL de l'image Ă  leur homologue immuable sur le CMS

Ce qui, je suppose, n'est pas impossible. Je veux juste m'assurer qu'il s'agit de la configuration proposée.

Les fournisseurs de CMS

Cela peut ĂȘtre vrai pour votre application, mais ce n'est pas le cas pour la majoritĂ© des applications.

Encore une fois, je ne suis pas seul ici. Il y a des tonnes de demandes similaires. Je vous demande de considérer cela.

https://spectrum.chat/next-js/general/how-would-you-handle-importing-remote-images-on-nextjs-static-export~30b2ba84-bc27-4da7-9ec8-21e4d5d287a3

du cÎté de gatsby également - https://github.com/gatsbyjs/gatsby/issues/14076

https://spectrum.chat/gatsby-js/general/adding-remote-images-during-node-creation~e704e6fb-24b2-46c6-b1fc-93189d2e28a4

https://github.com/njosefbeck/gatsby-source-stripe/#downloading -files

@sandys, cela n'a rien à voir avec le SSG RFC, alors n'hésitez pas à créer un nouveau problÚme lors de sa sortie.

cependant, je voulais juste mentionner que dans tous nos esprits, cela est Ă©troitement liĂ© Ă  SSG. Étant donnĂ© que le cas idĂ©al est que la commande d'exportation SSG le fasse. Cela n'est gĂ©nĂ©ralement pas nĂ©cessaire dans d'autres cas.
Dans le meilleur des cas, il s'agit d'une fonctionnalité facultative lors de la prochaine exportation.

Mais, comme vous le souhaitez, respectez votre décision.

Mais c'est quelque chose que next export ne fait mĂȘme pas actuellement. C'est pourquoi c'est une chose complĂštement nouvelle et sans rapport avec cette RFC.

Ce ne serait pas non plus avec getServerProps et le rendu Ă  la demande.

Les fournisseurs de CMS

oui, c'est logique. Mais cela signifie également que si vous utilisez des images dans votre projet et que vous souhaitez qu'elles soient optimisées et mises en cache, vous avez 2 choix :

  1. créer une configuration Webpack personnalisée
  2. utiliser un CMS externe

Éditer:

Et si j'ai bien compris, file-loader est déjà inclus pour CSS. Ne s'agit-il pas de l'activer également pour JS ?

@Janpot, le point spĂ©cifique mentionnĂ© par Sandeep est que les URL proviendraient d'une source externe, et non du projet lui-mĂȘme. L'inclusion de file-loader par dĂ©faut est une demande de fonctionnalitĂ© diffĂ©rente.

J'ai remarqué que pour les sites déployés sur ZEIT Now, lorsque j'ai une page avec une URL dynamique utilisant les nouvelles API statiques, pour les pages qui n'ont pas été générées statiquement à l'aide de unstable_getStaticPaths , la fonction unstable_getStaticProps s'exécute sur le serveur au moment de l'exécution, plutÎt que de renvoyer un 404.

Par exemple, j'ai une page /blog/[slug].js , dont getStaticPaths renvoie le tableau :

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

et mon getStaticProps a une certaine logique pour lire un fichier basé sur le slug. Lorsque je visite /blog/hello la page est pré-rendue comme prévu, mais lorsque je visite une page invalide comme /blog/doesnt-exist , alors getStaticProps s'exécute au moment de l'exécution et j'obtiens une erreur 500, plutÎt que un 404. Ou si j'ajoute la gestion des erreurs, la page s'affiche plutÎt qu'un 404, bien qu'elle ne soit pas répertoriée dans la sortie de getStaticPaths .

Cette logique est-elle intentionnelle ?

C'est une grande amélioration. Nous étions sur le point d'écrire des scripts de pré-construction pour faire exactement cela.
Je viens de tester le déplacement d'un de nos sites vers unstable_getStaticPaths et unstable_getStaticProps sur Next 9.2, et cela a bien fonctionné.

Nous avons une régression par rapport à exportPathMap : lors de la construction d'un chemin en utilisant exportPathMap , vous pouvez spécifier quelque chose comme ceci :

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

et la construction statique va construire

/path
   /to
     /page
       index.html

Lorsque vous retournez l'Ă©quivalent de unstable_getStaticPaths dans le modĂšle [slug].jsx ,

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

Next 9.2 génÚre '%2Fpath%2Fto%2Fpage` au lieu des répertoires imbriqués.

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

La crĂ©ation de rĂ©pertoires (correspondant au comportement exportPathMap existant) est importante pour la façon dont nous crĂ©ons les pages. Nous utilisons un seul fichier modĂšle, mais le chemin publiĂ© peut ĂȘtre arbitrairement imbriquĂ©.

@dpfavand dans ce cas, vous voudrez utiliser une route fourre-tout : https://nextjs.org/blog/next-9-2#catch -all-dynamic-routes

Potentiellement, nous pouvons vous avertir lorsque vous essayez de retourner un chemin comprenant des barres obliques, mais le comportement est correct lorsque vous utilisez [slug].js , dans votre cas, vous voulez [...slug].js .

Quand est-ce que cela devrait atterrir? Sera-ce dans un patch de 9.2 ou sa propre version mineure ?

Nous apprécions vraiment toute l'excitation autour de cette fonctionnalité. Comme mentionné ailleurs, nous ne partageons généralement pas les délais pour les fonctionnalités car nous voulons nous assurer qu'ils ont la bonne expérience de développeur, les bonnes contraintes et la pérennité.

Comme il s'agit d'une nouvelle fonctionnalité, ce sera mineur.

Ouais, je comprendrais ça normalement mais le blog 9.1.7 donnait l'impression
il était déjà à l'état sauvage.

Le vendredi 17 janvier 2020 Ă  17h05 Tim Neutkens [email protected]
a Ă©crit:

Nous apprécions vraiment toute l'excitation autour de cette fonctionnalité. Comme mentionné
ailleurs, nous ne partageons généralement pas les chronologies des fonctionnalités comme nous le souhaitons
s'assurer qu'ils ont la bonne expérience de développeur, les bonnes contraintes et l'avenir
preuve.

-
Vous recevez ceci parce que vous avez commenté.
RĂ©pondez directement Ă  cet e-mail, consultez-le sur GitHub
https://github.com/zeit/next.js/issues/9524?email_source=notifications&email_token=ADKINGF724256WCEFHBFIH3Q6ITRXA5CNFSM4JRPBEL2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVX5CNFSM4JRPBEL2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVX2HJKTDN5
ou se désinscrire
https://github.com/notifications/unsubscribe-auth/ADKINGBVCG6MFMOG5U2FGMDQ6ITRXANCNFSM4JRPBELQ
.

>

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

Existe-t-il quelque chose comme getStaticProps mais qui ne s'exécute qu'une seule fois pour l'ensemble de l'application au lieu de par page ?

Mon cas d'utilisation est que j'ai un contexte React ( PricingPlansContext ) qui est utilisé par plusieurs pages et je veux que les données (plans tarifaires) soient récupérées de mon serveur externe une seule fois, au moment de la construction ( next export ). Jamais à l'exécution et sans avoir à ajouter aux getStaticProps de chaque page.

EDIT : J'ai trouvé un commentaire connexe ci-dessus : https://github.com/zeit/next.js/issues/9524#issuecomment -574179540. Espérons que cela soit pris en compte.

J'utilise babel plugin-preval` pour cela, mĂȘme si j'ai aussi vu des gens Ă©crire un
json dans exportPathMa() avec next.config.js, qu'ils importent ensuite
dans leur code.

J'ai fini par Ă©crire un fichier json Ă  l'aide d'un script npm pour le moment, mais merci d'avoir suggĂ©rĂ© exportPathMap, c'est peut-ĂȘtre un meilleur endroit.

@dpfavand dans ce cas, vous voudrez utiliser une route fourre-tout : https://nextjs.org/blog/next-9-2#catch -all-dynamic-routes

Potentiellement, nous pouvons vous avertir lorsque vous essayez de retourner un chemin comprenant des barres obliques, mais le comportement est correct lorsque vous utilisez [slug].js , dans votre cas, vous voulez [...slug].js .

@timneutkens merci pour le suivi. J'ai essayĂ© deux mĂ©thodes sans succĂšs. Fondamentalement, lorsque vous spĂ©cifiez la valeur du slug sous forme de chaĂźne dans getStaticPaths , elle n'est pas du tout transmise Ă  getStaticProps . Lors du renvoi de la valeur slug sous forme de tableau, la construction Ă©choue car la valeur doit ĂȘtre une chaĂźne.

Cas 1, en supposant un fichier pages/[...slug].jsx , slug en tant que chaßne :

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

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

Dans le cas ci-dessus, params dans getStaticProps est un objet vide - pas slug clé

Cas 2, pages/[...slug].jsx , slug comme tableau,

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 };
}

Dans le cas 2, la construction Ă©choue avec

> 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' }

Je ne vois que les paramĂštres de chemin dans les exemples getStaticPaths ci-dessus. Sera-t-il possible d'utiliser des chemins SSG qui incluent des paramĂštres de requĂȘte ? Par exemple:

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

Je pense surtout du point de vue d'un site de commerce Ă©lectronique, oĂč il serait difficile de couvrir toutes les facettes de la recherche de produits dans les pathname d'une URL.

J'ai posté un message ici récemment et je n'ai pas eu de réponse - essentiellement, getStaticProps se comporte comme getServerProps lorsqu'un site est déployé sur ZEIT Now (c'est-à-dire en ignorant getStaticPaths et en traitant les demandes dynamiquement) - Je pense que c'est un bug ?

@dpfavand je vis exactement la mĂȘme chose aussi! Essayer de crĂ©er un site de dĂ©marrage pour agilitycms et nextjs avec un routage de page dynamique basĂ© sur les pages du CMS.

@timneutkens merci pour le suivi. J'ai essayé deux méthodes sans succÚs. Fondamentalement, lorsque vous spécifiez la valeur du slug sous forme de chaßne dans getStaticPaths , elle n'est pas du tout transmise à getStaticProps .

Cas 1, en supposant un fichier pages/[...slug].jsx , slug en tant que chaßne :

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

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

Dans le cas ci-dessus, params dans getStaticProps est un objet vide - pas slug clé

BTW, petit monde ! Merci encore d'avoir parlé à fastr_conf.

Salut @timneutkens ,

Je suis trÚs enthousiaste à l'idée de faire en sorte que next.js se comporte comme un générateur de site statique.

Je voudrais demander comment les mĂ©thodes getStaticProps et getStaticPaths peuvent ĂȘtre utilisĂ©es dans le cas oĂč un gros volume de donnĂ©es est demandĂ© une fois, puis utilisĂ© pour gĂ©nĂ©rer diffĂ©rentes pages.

Par exemple, j'utilise un client JavaScript SDK d'un CMS basé sur une API qui dispose d'une méthode pour récupérer tous les objets disponibles. Certains de ces objets représentent des pages de site.

const entries = await cmsSdkCient.getEntries();

Jusqu'à présent, j'ai utilisé la méthode exportPathMap pour récupérer toutes les entrées du CMS à la fois et générer une carte entre les chemins de ces pages et leurs données. La fonction exportPathMap fait deux choses :

  1. Fournit une carte des pages avec leurs données et les ssr: true qui sont consommés par getInitialProps au moment de l'exportation
  2. Écrit les mĂȘmes donnĂ©es, cette fois avec ssr: false , dans des fichiers init-props.json , placĂ©s dans le dossier correspondant au chemin de chaque page. Ensuite, lorsque getInitialProps est appelĂ© depuis le client, les donnĂ©es nĂ©cessaires sont chargĂ©es Ă  partir de init-props.json de la page correspondante.


next.config.js en utilisant 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;
    }, {});
  }
}


pages/ma_page.js en utilisant 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();
    });
  }
};

Je peux voir l'énorme avantage d'utiliser les méthodes getStaticProps et getStaticPaths qui réduiront une grande partie de mon code lié à l'enregistrement des fichiers JSON et à leur chargement à partir du client.

// 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 } }))
}

Ce qui me dérange, c'est la question de savoir comment optimiser le flux de travail pour apporter toutes les entrées une fois, plutÎt que de les récupérer à chaque fois lorsque getStaticProps ou getStaticPaths sont appelés ?

Une autre question n'est peut-ĂȘtre pas nĂ©cessairement liĂ©e Ă  ce problĂšme, mais parce que nous sommes dans le monde des SSG et des sources de donnĂ©es distantes, cela vaut la peine de se poser. En supposant que next.js s'exĂ©cute en mode dev, comment peut-on notifier Ă  next.js de rĂ©exĂ©cuter ces mĂ©thodes afin de rĂ©cupĂ©rer les donnĂ©es distantes et de reconstruire le site.

@smnh Puisqu'il s'agit de « juste JavaScript », vous pouvez récupérer vos entrées une fois et mettre en cache les résultats dans votre méthode de récupération de données. Lorsqu'il est à nouveau invoqué dans les méthodes getStatic* d'une autre page, le réseau ne sera plus touché.

Quant Ă  votre deuxiĂšme question, elle le fait automatiquement. ExĂ©cutez next dev et vous ĂȘtes prĂȘt Ă  partir.

Je ne vois que les paramĂštres de chemin dans les exemples getStaticPaths ci-dessus. Sera-t-il possible d'utiliser des chemins SSG qui incluent des paramĂštres de requĂȘte ? Par exemple:

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

Je pense surtout du point de vue d'un site de commerce Ă©lectronique, oĂč il serait difficile de couvrir toutes les facettes de la recherche de produits dans les pathname d'une URL.

Je ne pense pas que cela ait du sens dans le contexte de ssg. SSG gĂ©nĂšre un fichier pour chaque entrĂ©e - les paramĂštres de requĂȘte ne font pas partie du nom de fichier, vous auriez donc besoin d'une couche serveur pour rĂ©Ă©crire les requĂȘtes dans un fichier rĂ©el. (Quel serait votre nom de fichier statique dans l'exemple ci-dessus ?) Je suggĂ©rerais d'envisager de prĂ©-afficher la vue par dĂ©faut (ce que vous obtenez si vous visitez la page sans facettes) et de mettre Ă  jour cĂŽtĂ© client s'il y a des paramĂštres de requĂȘte sur la demande. Mais cela devient un problĂšme au-delĂ  de ce SSG RFC.

@dpfavand je vis exactement la mĂȘme chose aussi! Essayer de crĂ©er un site de dĂ©marrage pour agilitycms et nextjs avec un routage de page dynamique basĂ© sur les pages du CMS.

@timneutkens merci pour le suivi. J'ai essayé deux méthodes sans succÚs. Fondamentalement, lorsque vous spécifiez la valeur du slug sous forme de chaßne dans getStaticPaths , elle n'est pas du tout transmise à getStaticProps .
Cas 1, en supposant un fichier pages/[...slug].jsx , slug en tant que chaßne :

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

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

Dans le cas ci-dessus, params dans getStaticProps est un objet vide - pas slug clé

BTW, petit monde ! Merci encore d'avoir parlé à fastr_conf.

Hey! L'équipe Nextjs a commencé à résoudre ce problÚme, un ticket est ouvert pour résoudre certains problÚmes supplémentaires avec l'implémentation actuelle de Canary : https://github.com/zeit/next.js/issues/10190

@smnh, ce que je

Pour les reconstructions, j'ai configuré des webhooks dans le CMS pour déclencher des crochets de construction Netlify lorsque le contenu pertinent change. GetStaticProps peut alors simplement récupérer le contenu spécifique à la page.

Merci @zeusdeux
RĂ©:

Quant Ă  votre deuxiĂšme question, elle le fait automatiquement. ExĂ©cutez le prochain dev et vous ĂȘtes prĂȘt Ă  partir.

Si je les cache dans un module puis modifie les donnĂ©es dans le CMS, comment le cache sera invalidĂ© et rĂ©exĂ©cutĂ© par dev , mais sans arrĂȘter next.js et le rĂ©exĂ©cuter :)

Si je les cache dans un module puis modifie les donnĂ©es dans le CMS, comment le cache sera invalidĂ© et rĂ©exĂ©cutĂ© par dev , mais sans arrĂȘter next.js et le rĂ©exĂ©cuter :)

getStaticPaths n'est invoqué que dans une version de production, vous ne pouvez donc indiquer à la méthode d'extraction de mettre en cache dans l'état du module qu'une fois appelée à partir de cette fonction.

HĂ©, je n'ai pas vu si quelqu'un rencontre le mĂȘme problĂšme que moi.

Disons que j'ai la mĂȘme page sur plusieurs routes avec unstable_getStaticProps :

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

Le code source est le mĂȘme pour les deux pages, il n'est donc pas nĂ©cessaire de le dupliquer. Ainsi, pour le premier fichier contenant du code source avec logique, le second importe uniquement le premier comme export { default } from './[city]'; .

Mais il renvoie une erreur indiquant que les donnĂ©es de getStaticProps ne sont pas dĂ©finies. Si je copie le mĂȘme code dans les deux fichiers, cela fonctionne.

@homoky vous devez réexporter les méthodes :

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

J'ai essayé SSG, mais sans succÚs.

Le code ci-dessous avec la v9.2.1 devrait-il entraßner SSG ?

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

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

export default Page

La sortie de ma console de next build montre :

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 doit ĂȘtre exportĂ© au lieu d'ĂȘtre attachĂ© au composant de page, par exemple

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

@joostmeijles unstable_getStaticProps doit ĂȘtre exportĂ© au lieu d'ĂȘtre attachĂ© au composant de page, par exemple

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

Merci, ça résout.

Si quelqu'un veut voir un exemple de travail de bout en bout, créer des pages dynamiques (à partir d'un CMS) avec une route fourre-tout et SSG, consultez https://github.com/agility/agilitycms-next-starter- ssg.

J'ai Ă©tĂ© perplexe plusieurs fois et j'ai pensĂ© que cela pourrait ĂȘtre utile pour d'autres.

Comment puis-je accĂ©der aux prochaines routes API lors de la construction avec getStaticProps lors du dĂ©ploiement sur zeit.co/now ? La rĂ©cupĂ©ration isomorphe nĂ©cessite une URL absolue ; localement, cela fonctionne avec http://localhost :3000 mais pas avec le dĂ©ploiement actuel (ou je l'ai mal fait đŸ€·â€â™‚ïž). Des idĂ©es?

Si j'ai raison, les routes API vont ĂȘtre dĂ©ployĂ©es en tant que fonctions sans serveur et je suppose qu'elles ne sont pas prĂȘtes pendant le processus de construction ?

Vous voudrez appeler directement la fonction de votre route api car cela coûte beaucoup moins cher que de passer par http.

Vous voudrez appeler directement la fonction de votre route api car cela coûte beaucoup moins cher que de passer par http.

Des ressources que je peux lire dans les docs sur ce sujet ? Je suis en pleine migration vers zeit.co/now :)

Pris au pied de la lettre, importez et appelez la fonction :

import MyFunction from '../lib/somewhere'


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

Autre question : Sera getStaticProps / getStaticPaths et getServerProps cÎte à cÎte ? Par exemple, si j'ai pré-rendu certaines pages avec SSG, mais si aucune n'est trouvée dans le cache CDN, alors il reviendra à SSR pour générer la page à la demande ?

getStaticProps se repliera sur SSR et ajoutera le résultat au cache,

getStaticProps se repliera sur SSR et ajoutera le résultat au cache,

@lfades , si je vous comprends bien, alors je suis super 😍 Ă  ce sujet, car cela signifie que je peux prĂ©-rendre quelques-unes des pages populaires, au lieu de rechercher et de gĂ©nĂ©rer plusieurs milliers de pages Ă  l'avance.

Mais juste pour ĂȘtre sĂ»r de bien comprendre... Disons que j'ai une page de chemin dynamique /products/[productId].js . Si je fournis un getStaticProps , et un nombre limitĂ© de rĂ©sultats de getStaticPaths , alors vous dites si /products/123 n'est pas trouvĂ© dans le cache CDN (parce que c'Ă©tait t dans getStaticPaths ), il reviendra Ă  SSR, exĂ©cutera getStaticProps , puis mettra en cache le rĂ©sultat en tant que page statique ?

Question de suivi : cela fonctionnera-t-il également si je ne fournis pas du tout de getStaticPaths ?

@flintinatux Oui et oui

getStaticProps se repliera sur SSR et ajoutera le résultat au cache

C'est un problĂšme car il n'y a aucun moyen de faire des 404, car getStaticProps ne permet pas de changer l'objet res - soit il sera 200, soit 500 s'il y a une erreur lors de l'appel de la fonction.

Est-ce que c'est prévu de changer ?

@davidbailey00 lors de la création de sites Web statiques, les pages 404 n'ont déjà pas le code d'état 404.

Bien sûr, si je fais une exportation statique complÚte, il n'y a aucun moyen de faire des codes d'état, car tout n'est qu'un fichier. Je parle du déploiement de sites hybrides en utilisant getStaticProps vers ZEIT Now - il semble qu'il devrait respecter getStaticPaths et servir 404 pages, plutÎt que de forcer le rendu de toutes les pages correspondant à un chemin dynamique indépendamment de cela.

Ce n'est pas seulement comment cela fonctionne sur Now, c'est la mĂȘme chose sur next start .

Je vais répéter comme dit plus tÎt : c'est expérimental et tout peut encore changer de comportement.

Mais il est possible de servir 404 pages avec getServerProps ou getInitialProps - si getStaticProps ignore getStaticPaths lors de l'examen du code de réponse, alors c'est complÚtement non viable pour tout site qui se soucie de bon référencement.

Nous allons probablement introduire d'autres façons de gĂ©rer les codes d'Ă©tat, mais gardez Ă  l'esprit que la plupart des sites statiques (par exemple, CRA) acheminent /* vers index.html oĂč 404 est toujours un 200.

Salut les gars, j'ai une question directe, je construis un site Web simple en utilisant le nouveau [unstable_]getStaticProps pour SSG certaines des pages. Tout fonctionne bien jusqu'à présent, à l'exception de l' ampli .

Si une page contient [unstable_]getStaticProps , alors amp est dĂ©sactivĂ©. Voici un exemple simple fonctionnant avec la prochaine v9.2.1 oĂč vous pouvez vĂ©rifier que :

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;

Une aide pour comprendre comment avoir des pages SSG avec des données et amp fonctionnent ?

Salut, que diriez-vous de prendre en charge getStaticProps pour le composant App ( _app.tsx ) c'est-à-dire pour des cas tels que la récupération de données communes pour tous les composants de page pendant la phase de construction ?

Salut, que diriez-vous de prendre en charge getStaticProps pour le composant App ( _app.tsx ) c'est-à-dire pour des cas tels que la récupération de données communes pour tous les composants de page pendant la phase de construction ?

@ pkral78 Je peux vous dire comment je

J'ai crĂ©Ă© un Layout avec l'approche "Layout as a Higher Order Component (HOC)" (plus dans les documents d'apprentissage đŸ€·â€â™‚ïž).

Quoi qu'il en soit, j'ai créé une mise en page comme la suivante (juste un exemple):

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;

Et puis dans la page sur laquelle vous souhaitez utiliser cette approche, vous pouvez simplement ajouter le HOC (vous devez explicitement exporter le [unstable_]getStaticProps et l'ampli ne fonctionnant pas ensemble), mais j'ai trouvĂ© une "bonne façon" d'avoir une demande de haut niveau et requĂȘtes SSG par page.

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;

J'aimerais sous-entendre si c'est une bonne approche. Dans mon cas, j'utilise cette technique pour interroger les liens dans le contenu parent et par page dans les pages. J'espÚre que ça aide.

@robertovg Vous devez exporter au niveau du module car le code est arborescent. La façon dont vous l'avez modélisé entraßne l'envoi de plus de code cÎté client.

@timneutkens Pourriez-vous peut-ĂȘtre proposer une meilleure solution pour ce petit exemple ? J'essayais juste d'avoir Ă  la fois une "requĂȘte SSG au niveau de la mise en page" et une "requĂȘte SSG au niveau de la page" et j'ai pensĂ© Ă  cette approche de mise en page HOC.

La principale contrainte pour moi Ă©tait d'"exporter explicitement [unstable_]getStaticProps" que vous devez avoir sur chaque page pour marquer comme page SSG.

J'apprécierais vraiment aussi plus d'informations sur la compatibilité de l' ampli + SSG , j'ai demandé plus tÎt.

Merci

@robertovg Tout d'abord,

import Layout from '../components/layout'

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

export default Page

Et puis pour getStaticProps récupérez les données partagées à l'aide d'une méthode d'un autre module, de sorte que l'exemple complet pourrait ressembler à :

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 Tout d'abord,

import Layout from '../components/layout'

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

export default Page

Et puis pour getStaticProps récupérez les données partagées à l'aide d'une méthode d'un autre module, de sorte que l'exemple complet pourrait ressembler à :

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

Je vois et je comprends cette solution, mais le problÚme que j'essayais de résoudre était de savoir comment faire évoluer l'utilisation des données partagées.
Par exemple, si vous avez un <Header /> qui utilise le sharedData pour obtenir les liens et que ceux-ci proviennent d'un CMS Headless. Vous devez injecter le <Header /> tant qu'enfant du <Layout /> avec des accessoires ou une autre solution. Et vous devez répéter l'injection de <Header /> dans toutes les pages que vous souhaitez utiliser.

Avec l' approche HOC, vous ajouteriez simplement le <Header /> une fois dans le HOC.

C'est pourquoi j'ai pensé que c'était un bon point celui soulevé par @pkral78 , pour éviter si possible la duplication de code.

C'est pourquoi j'ai pensé que c'était un bon point celui soulevé par @pkral78 , pour éviter si possible la duplication de code.

C'Ă©tait dans ma tĂȘte. La page _app devrait avoir son getStaticProps qui est appelĂ© une fois lors du rendu de la premiĂšre page, puis passe le props enregistrĂ© aux pages rendues suivantes. Mais je me demande toujours si c'est un concept appropriĂ©.

Je ne sais pas si ce genre de chose est un cas d'utilisation prévu, mais cela ne semble pas fonctionner :

// /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>
  );
}

MĂȘme s'il ne s'agit pas d'un cas d'utilisation prĂ©vu, il enregistre une erreur qui semble un peu suspecte :

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

Éditer:

Oh, ok, ça se résout quand je le fais

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

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

Cela se plaint du fait que le chemin de votre fichier d'importation est dynamique

Le jeu. 30 janvier 2020 Ă  00h29, Jan Potoms [email protected] a Ă©crit :

Je ne sais pas si ce genre de chose
https://codesandbox.io/s/nifty-cache-jspqr est un cas d'utilisation prévu, mais
ça n'a pas l'air de fonctionner :

// /pages/[...slug].jsximport ReactDOMServer de "react-dom/server" ;
exporter la fonction async unstable_getStaticProps({ paramÚtres : { slug } }) {
// est-ce mĂȘme sĂ»r ?
const filePath = "../content/" + slug.join("/") + ".mdx" ;
const { par défaut : Component } = wait import(filePath);
const content = ReactDOMServer.renderToStaticMarkup(Component);
revenir {
accessoires : { titre : slug.join(" "), contenu }
} ;
}
Exporter la fonction par défaut Page ({ titre, contenu }) {
revenir (


{Titre}




);
}

MĂȘme s'il ne s'agit pas d'un cas d'utilisation prĂ©vu, il enregistre une erreur qui semble
un peu suspect :

[ avertir ] ./pages/[...slug].jsx
Dépendance critique : la demande d'une dépendance est une expression

-
Vous recevez ceci parce que vous avez été mentionné.
RĂ©pondez directement Ă  cet e-mail, consultez-le sur GitHub
https://github.com/zeit/next.js/issues/9524?email_source=notifications&email_token=AAADKRKOL34WKTG7J5QFRJ3RAIGPBA5CNFSM4JRPBEL2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVES5WYZLOJKT ,
ou se désinscrire
https://github.com/notifications/unsubscribe-auth/AAADKRIWNA2DSMWFRGD453DRAIGPBANCNFSM4JRPBELQ
.

C'est pourquoi j'ai pensé que c'était un bon point celui soulevé par @pkral78 , pour éviter si possible la duplication de code.

C'Ă©tait dans ma tĂȘte. La page _app doit avoir son getStaticProps qui est appelĂ© une fois lors du premier rendu de page, puis passe le props enregistrĂ© aux pages rendues suivantes. Mais je me demande toujours si c'est un bon concept.

@pkral78 , C'est peut-ĂȘtre parce que dans la plupart des sites SSG que j'imagine implĂ©mentĂ©s avec Next, j'aimerais avoir une "piĂšce commune" (En-tĂȘte, pied de page, barres latĂ©rales...). Et pourquoi ne pas simplement faire la requĂȘte pour cet Ă©lĂ©ment commun dans le _app si vous en avez besoin, et le rendre disponible dans les pages enfants sans avoir Ă  le faire manuellement sur chaque page.

Mon seul souci est que si vous le mettez dans le _app.js , nous ne pourrions pas avoir plus d'une "piĂšce commune" en fonction de la page. Avec l'idĂ©e que je faisais du prototypage, je voulais pouvoir l'avoir dans le Layout car cela nous permettrait d'avoir plusieurs Layouts en fonction du type de page que l'on veut rendre, "c'est pourquoi j'ai appelĂ© withSSGLayout pour mon HOC parce que je prĂ©voyais d'avoir non seulement des pages SSG, mais Ă©galement des pages SSR et entiĂšrement clientes, ou mĂȘme plus d'un SSGLayout. Cela pourrait ĂȘtre fait si Layouts pouvait Ă©galement ĂȘtre responsable d'une mĂ©thode parent getStaticProps .

Quoi qu'il en soit, avoir SSG dans Next en fera l'outil pour tout type de site Web 🙌

@Janpot en ce qui concerne https://github.com/zeit/next.js/issues/9524#issuecomment -580012327

Peut fortement recommander de ne jamais utiliser de chemins dynamiques dans import() . Il regroupera tous les fichiers possibles sous le chemin d'accÚs au bundle JS et réduira considérablement les performances de construction.

@timneutkens Bien sûr, c'est logique. getStaticProps uniquement destiné à interroger des API externes, pas le systÚme de fichiers ?

@Janpot, vous pouvez lire Ă  partir du systĂšme de fichiers, mais vous finirez souvent par interroger une API externe.

@timneutkens Ok, mieux vaut utiliser @mdx-js/runtime alors, au lieu de compter sur @next/mdx je suppose.

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 ouais ! vous pouvez également utiliser un simple markdown, c'est ce que nous faisons pour nextjs.org/docs.

Concernant https://github.com/zeit/next.js/issues/9524#issuecomment -580207073, c'est exactement comme j'utilise actuellement Next avec SSR. J'ai une requĂȘte GraphQL qui est effectuĂ©e au niveau de la mise en page, et son contenu est partagĂ© avec les composants communs de l'application (Navbar, Footer et les enfants dynamiques). Ensuite, les enfants dynamiques effectuent gĂ©nĂ©ralement une autre demande GraphQL pour le contenu spĂ©cifique Ă  la page.

Ainsi, avoir un moyen de réutiliser cela semble important, je ne voudrais pas avoir à dupliquer le code sur chaque page pour récupérer ces données communes.

Hey!
Je suis assez nouveau ici. Je viens de commencer Ă  travailler sur la migration de l'application vers NextJS.

Il existe un cas d'utilisation de base qui bénéficierait grandement de cette fonctionnalité - des versions multilingues. L'application Web sur laquelle je travaille a environ 16 versions linguistiques avec plus de 100 000 pages vues par jour et pouvoir générer de maniÚre statique, par exemple, une page de destination serait fantastique, mais le problÚme est le routage.

Avec le rendu cĂŽtĂ© serveur, je peux lire les en-tĂȘtes de requĂȘte ou les cookies et afficher la version linguistique appropriĂ©e, mais sans cela, est-ce que la seule solution pour crĂ©er des chemins pour chaque version comme /en, /de, /fr et sur "/" fait que NextJS ne fait que rediriger ?

AprÚs avoir appris à propos de ReactDOMServer.renderToStaticMarkup je l'ai ajouté à ma fonction unstable_getStaticProps et j'ai trouvé qu'il avait amélioré mon score de vitesse de page (mobile) de 96 à 100 grùce à l'amélioration drastique du temps d'interaction et du délai maximal potentiel de la premiÚre entrée. .

Je peux visiter la page sans JavaScript et elle se charge bien, il semble donc que React travaille sur le chargement de la page, malgré l'utilisation de SSG.

C'est peut-ĂȘtre un manque de comprĂ©hension de React, mais je m'attendrais Ă  ce que les performances avec et sans JavaScript soient les mĂȘmes, et je ne m'attendrais pas Ă  ce que le prĂ©-rendu des composants aide (je pensais que c'Ă©tait ce que faisait SSG).

Est-ce que l'attendu, un bug ou quelque chose que je fais mal?

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

@JosephDuffy

il semble donc que React travaille sur le chargement de la page, malgré l'utilisation de SSG.

Il hydrate le DOM. Essentiellement:

  1. votre navigateur charge le SSR html dans le DOM du navigateur
  2. React reconstruit tout le DOM virtuel
  3. React parcourt ces DOM et les synchronise (hydratation)

Si votre contenu est vraiment statique, comme dans le cas des effets secondaires ou des gestionnaires d'événements, les étapes 2 et 3 sont en quelque sorte inutiles. Avec votre méthode, vous réduisez essentiellement votre arbre de composants à 1 composant avec 1 attribut, ce qui est trÚs rapide pour React à rendre et à hydrater. (+ dangerouslySetInnerHTM est ignoré pendant l'hydratation)

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

Gardez à l'esprit que les gestionnaires d'événements et les effets secondaires ne fonctionneront pas avec cette méthode.

Éditer:

Une idĂ©e pourrait ĂȘtre de permettre d'omettre l'exportation par dĂ©faut sur une page si getStaticProps renvoie du html statique. c'est Ă  dire

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

Étant donnĂ© que rien n'a besoin d'ĂȘtre rendu cĂŽtĂ© client, next.js peut exclure son environnement d'exĂ©cution de la page et simplement insĂ©rer le code HTML que getStaticProps renvoyĂ©. Et cela fonctionnerait de la mĂȘme maniĂšre que si dangerouslySetInnerHTML Ă©tait utilisĂ© sur le nƓud racine next.js.
Je suppose que ce serait plus facile Ă  mettre en Ɠuvre qu'une hydratation partielle, quoique moins puissante. RĂ©utiliser la terminologie de React lui-mĂȘme ici pourrait rĂ©duire la confusion sur le fonctionnement de cette fonctionnalitĂ©.

J'essaie de migrer un site statique vers Next.js et j'aimerais rediriger toutes les variantes .html des articles de blog vers des versions ne se terminant pas par .html. Il semble que getStaticProps n'obtienne pas actuellement de contexte, je ne peux donc pas vérifier le slug entrant et la redirection. Ce serait utile si getStaticProps avait un contexte complet afin que je puisse faire des choses conditionnelles avec.

@nodabladam, il semble que vous recherchiez la RFC Custom Routes : #9081.

Cette RFC vous permettrait de définir quelque chose comme ceci :

// 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
      }
    ];
  }
};

Vous pouvez actuellement essayer cette fonctionnalité sous la clé experimental :

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

J'ai implémenté getStaticProps et getStaticPathNames sur un de mes projets (environ 8K pages).

Cependant, les fichiers de sortie sont comptés dans la limite de 10 Ko de fichiers par déploiement. Avec 8 Ko de pages, vous obtenez 16 Ko de fichiers de sortie, car chaque page reçoit également un fichier json.

Est-il prévu d'augmenter cette limite? Ou puis-je contourner cette limite ?

J'ai le mĂȘme problĂšme.
Je comprends qu'ils cherchent à lever cette limite, mais je ne sais pas quand elle sera déployée.

J'utilise donc getStaticProps sur toutes les pages et getStaticPaths uniquement sur certaines d'entre elles et cela fonctionne (ma page de produit génÚre 70% du nombre total de pages, donc je n'y ai mis aucun getStaticPaths). Je reste sous la limite mais ce n'est pas parfait, le premier chargement est assez long et difficile de gérer les erreurs 404.

J'ai le mĂȘme problĂšme.
Je comprends qu'ils cherchent à lever cette limite, mais je ne sais pas quand elle sera déployée.

J'utilise donc getStaticProps sur toutes les pages et getStaticPaths uniquement sur certaines d'entre elles et cela fonctionne (ma page de produit génÚre 70% du nombre total de pages, donc je n'y ai mis aucun getStaticPaths). Je reste sous la limite mais ce n'est pas parfait, le premier chargement est assez long et difficile de gérer les erreurs 404.

J'espĂšre qu'ils augmenteront la limite bientĂŽt, mais j'espĂšre que ce ne sera pas 20K.. cela ne me suffira pas Ă  long terme.

Je veux Ă©viter les premiers temps de chargement avec getStaticPaths.. Je devrai peut-ĂȘtre chercher d'autres solutions que Zeit Now

Next.js exposera également automatiquement un point de terminaison d'API qui renvoie le résultat de l'appel de getServerProps. [...] Next.js récupérera ce point de terminaison d'API exposé pour obtenir les données JSON qui sont transformées en accessoires nécessaires pour rendre la page cÎté client.

Next.js rĂ©cupĂ©rera les donnĂ©es de ce point de terminaison avant de modifier la route et de rendre le composant de page (il ne peut pas, du moins par dĂ©faut, le faire autrement). Ainsi, l'utilisateur peut rencontrer un site extrĂȘmement accrocheur en raison de la gĂ©nĂ©ration statique de certaines pages, mais s'il clique sur un lien vers une page SSR, le site "se bloquera" soudainement un peu avant que l'itinĂ©raire ne change.

Existe-t-il une mĂ©thode recommandĂ©e pour charger le composant _first_ afin qu'il puisse ĂȘtre rempli avec des indicateurs de chargement, des espaces rĂ©servĂ©s animĂ©s, etc. ? (Au lieu de les ajouter Ă  la page actuelle.) Si non, cela pourrait-il ĂȘtre pertinent pour les nouvelles fonctionnalitĂ©s proposĂ©es ? Je l'ai rĂ©alisĂ© en utilisant une combinaison de getInitialProps et de crochets dans la mĂ©thode de rendu, mais cela semble dĂ©sordonnĂ©.

Je pense que ce modÚle UX (changement de page instantané) est préféré par beaucoup (la plupart ?), mais je n'en ai pas encore vu d'exemples utilisant Next.js. Je n'utilise le framework que depuis quelques jours, alors corrigez-moi si je me trompe.

Vraiment excité par les nouvelles fonctionnalités! Merci pour votre travail.

@nicoqh , vos prĂ©occupations concernant les transitions de page ne sont pas spĂ©cifiques Ă  SSG, car le blocage se produit avec le getInitialProps actuel. J'utilise nprogress pour au moins afficher une barre de progression en haut pendant le chargement de la page suivante, mais je vois aussi cet exemple d'avoir des transitions de page lĂ©gitimes qui semblent plus proches de ce que vous dĂ©crivez. Je ne l'ai pas essayĂ© moi-mĂȘme, mais j'espĂšre que cela vous aidera avec ce dont vous avez besoin :
https://github.com/zeit/next.js/tree/canary/examples/with-next-page-transitions

Il semble que le fichier json /_next/data/BUILD_ID/<file>.json renvoyĂ© ne respecte pas assetPrefix. Cela amĂšne le fichier Ă  404 pour moi dans mon environnement de production car j'ai une configuration qui s'attend Ă  ce que tout _next soit un actif qui passe par CDN. Ces fichiers json devraient finalement ĂȘtre acheminĂ©s via l'assetPrefix (CDN), n'est-ce pas ?

J'ai le mĂȘme problĂšme.
Je comprends qu'ils cherchent à lever cette limite, mais je ne sais pas quand elle sera déployée.
J'utilise donc getStaticProps sur toutes les pages et getStaticPaths uniquement sur certaines d'entre elles et cela fonctionne (ma page de produit génÚre 70% du nombre total de pages, donc je n'y ai mis aucun getStaticPaths). Je reste sous la limite mais ce n'est pas parfait, le premier chargement est assez long et difficile de gérer les erreurs 404.

J'espĂšre qu'ils augmenteront la limite bientĂŽt, mais j'espĂšre que ce ne sera pas 20K.. cela ne me suffira pas Ă  long terme.

Je veux Ă©viter les premiers temps de chargement avec getStaticPaths.. Je devrai peut-ĂȘtre chercher d'autres solutions que Zeit Now

@erhankaradeniz et @ziltosh, nous devrions le déployer trÚs bientÎt. Si vous souhaitez obtenir de l'aide avec cela dÚs que possible, vous pouvez me contacter directement ou

J'ai le mĂȘme problĂšme.
Je comprends qu'ils cherchent à lever cette limite, mais je ne sais pas quand elle sera déployée.
J'utilise donc getStaticProps sur toutes les pages et getStaticPaths uniquement sur certaines d'entre elles et cela fonctionne (ma page de produit génÚre 70% du nombre total de pages, donc je n'y ai mis aucun getStaticPaths). Je reste sous la limite mais ce n'est pas parfait, le premier chargement est assez long et difficile de gérer les erreurs 404.

J'espĂšre qu'ils augmenteront la limite bientĂŽt, mais j'espĂšre que ce ne sera pas 20K.. cela ne me suffira pas Ă  long terme.
Je veux Ă©viter les premiers temps de chargement avec getStaticPaths.. Je devrai peut-ĂȘtre chercher d'autres solutions que Zeit Now

@erhankaradeniz et @Ziltosh, nous devrions le déployer trÚs bientÎt. Si vous souhaitez obtenir de l'aide avec cela dÚs que possible, vous pouvez me contacter directement ou

Merci @kvangundy
Je vous ai contacté sur Twitter à ce sujet ;-)

@erhankaradeniz Pouvez-vous envoyer un e-mail Ă  [email protected] Ă  la place ? De cette façon, il se retrouve correctement dans notre systĂšme.

@flintinatux , merci pour le conseil. J'ai vu l'exemple, et cela n'aide pas à charger le composant de page avant de charger les données, donc les espaces réservés dans la page, etc. ne sont pas possibles. C'est un exemple intéressant, cependant, merci!

Je suppose que cela ne sera pas abordé dans ce numéro, ce qui signifie que c'est hors sujet, donc je vais trouver un autre endroit pour en discuter :)

Je pense que l'approche consistant à diviser getInitialProps en getStaticProps & getServerProps est beaucoup plus propre ! J'ai une question concernant la façon dont cela affecte notre cas d'utilisation :
Nous souhaitons créer 2 versions distinctes : une version statique pour notre site de production et une version utilisant SSR pour un environnement d'édition.

Je pensais pouvoir attacher sous condition getStaticProps vs getServerProps tant que méthodes statiques en fonction de la version (similaire à https://github.com/zeit/next.js/issues/9524#issuecomment- 558617056), mais je ne sais pas s'il sera possible de les exporter conditionnellement tels quels. Des idées si cela sera possible de prendre en charge dynamique/statique en fonction de la version ?

En ce qui concerne :

RFC sera mis à jour pour refléter les changements plus tard, toujours en itérant sur l'utilisation du monde réel dans nos applications.

Je me demande s'il existe un moyen d'utiliser une sorte de route gĂ©nĂ©rique pour attraper des routes inconnues au moment de la construction. C'est gĂ©nial que je puisse rendre des pages statiques Ă  partir de donnĂ©es CMS par exemple, mais que se passe-t-il si quelqu'un ajoute un nouvel Ă©lĂ©ment ? Je n'ai pas de page statique pour ça. Ce problĂšme me gratte la tĂȘte depuis longtemps.

J'ai configuré une route dynamique pour rendre les pages statiques _pages/[slug].js_. _getStaticPaths_ obtient toutes les pages que je veux rendre statiquement. J'ai _getStaticProps_ pour interroger les données et les transmettre à la fonction de rendu. Toutes les pages données dans _getStaticPaths_ sont rendues sous forme de fichiers HTML dans _.next/server/static_ lors de la construction. Super!

Maintenant, je lance npm run start et ces pages comme il se doit. Mais demander une URL manquante (comme _/foo_) génÚre de nouveaux fichiers HTML et JSON statiques dans _.next/server/static_. Ce n'est pas bien. Comment puis-je faire en sorte que le serveur redirige toutes les autres URL vers _pages/_error.js_ ?

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

Nous couvrons cela aussi.

Maintenant, je lance npm run start et ces pages comme il se doit. Mais demander une URL manquante (comme /foo) génÚre de nouveaux fichiers HTML et JSON statiques dans .next/server/static. Ce n'est pas bien. Comment puis-je faire en sorte que le serveur redirige toutes les autres URL vers pages/_error.js ?

Il s'agit toujours d'un comportement en vol et non inattendu pour le moment.

Encore une fois, rappelez-vous que vous utilisez une fonctionnalité expérimentale et que le comportement peut changer à tout moment. Les choses vont changer et potentiellement se briser entre toutes les versions pendant que vous l'utilisez quand ce n'est pas stable.

@timneutkens Merci ! Je comprends l'instabilitĂ©. Avez-vous une idĂ©e de comment gĂ©rer cela? J'ai parcouru le code et j'ai remarquĂ© que lancer une erreur dans _unstable_getStaticProps_ rend la page d'erreur. Cela pourrait ĂȘtre une bonne façon de procĂ©der. J'aurais juste besoin d'un moyen de transmettre l'erreur telle quelle Ă  _pages/_error.js_. Je voudrais l'envoyer 404. Maintenant, il va jusqu'Ă  500.

J'ai déjà posté cela plusieurs fois dans d'autres fils de discussion, mais "aller à _error" est un comportement inattendu, à partir de maintenant, votre page devrait afficher un état 404. Dit simplement if(!data.something) { return <My404Component /> } , puis My404Component devrait définir les balises méta noindex .

Vraiment? La documentation indique clairement d'utiliser _pages/_error.js_ pour les 404.

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

@jiv-e c'est pour les 404 causés par :

  • Page non trouvĂ©e
  • Fichier introuvable

Si vous avez des routes dynamiques, vous devez gérer le cas "404" comme je l'ai dit, par exemple comme https://nextjs.org/docs/advanced-features/custom-error-page#reusing -the-built-in-error- page

J'ai compris! Merci!

J'aimerais utiliser getStaticProps pour rĂ©cupĂ©rer les clĂ©s de traduction/langue au moment de la construction, car elles changeront trĂšs probablement 1 Ă  2 fois par mois ou mĂȘme par an. De plus, vous n'en avez pas besoin en tant que JSON/props dans le DOM. Le problĂšme est que je ne veux pas transmettre de clĂ©s dans l'arborescence au composant oĂč je les utilise rĂ©ellement - Quelles approches conviennent Ă  mon cas d'utilisation ?

crochet useTranslation() (ou HOC) avec contexte ?

Ce serait bien si le AppTree faisait partie du contexte NextGetStaticProps ( getStaticProps({ AppTree }) ). Sinon, il ne sera pas possible d'exécuter des choses comme apollos getDataFromTree sur ssg.

À ce stade, nous ne prĂ©voyons pas d'autoriser la traversĂ©e d'AppTree dans getStaticProps car c'est vraiment mauvais pour les performances (rĂ©troaction cohĂ©rente des entreprises). Lorsque vous ajoutez getStaticProps Ă  une page, il passe toujours par getInitialProps de _app pour permettre une adoption incrĂ©mentielle, donc cela fonctionnerait toujours vraiment avec Apollo.

Ce serait bien si nous pouvions avoir des fonctionnalitĂ©s amp: 'hybrid' et SSG en mĂȘme temps.
Cela pourrait ĂȘtre rĂ©alisĂ© en crĂ©ant deux fichiers pour une page comme celle-ci, c'est-Ă -dire :

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

Cela permettrait aux proxys de se rĂ©soudre en un document amp basĂ© sur le paramĂštre de requĂȘte ?amp=1 .

Ce serait bien si nous pouvions avoir des fonctionnalitĂ©s amp: 'hybrid' et SSG en mĂȘme temps.
Cela pourrait ĂȘtre rĂ©alisĂ© en crĂ©ant deux fichiers pour une page comme celle-ci, c'est-Ă -dire :

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

Cela permettrait aux proxys de se rĂ©soudre en un document amp basĂ© sur le paramĂštre de requĂȘte ?amp=1 .

Exactement @Dactune , c'est le seul inconvénient que je vois pour commencer à utiliser SSG déjà sur des projets comme je le commentais dans ce fil il y a quelque temps.

??

@jansedlon J'ai fait un article de blog pour répondre à votre question :

Je me demande s'il existe un moyen d'utiliser une sorte de route gĂ©nĂ©rique pour attraper des routes inconnues au moment de la construction. C'est gĂ©nial que je puisse rendre des pages statiques Ă  partir de donnĂ©es CMS par exemple, mais que se passe-t-il si quelqu'un ajoute un nouvel Ă©lĂ©ment ? Je n'ai pas de page statique pour ça. Ce problĂšme me gratte la tĂȘte depuis longtemps.

https://paqmind.com/en/blog/ssr-is-not-the-future

(ne pas poster ici car c'est trop gros)

@ivan-kleshnin J'ai jetĂ© un coup d'Ɠil rapide et ça a l'air super excitant ! Vous m'avez peut-ĂȘtre fait gagner des centaines d'heures ! Merci beaucoup, je regarderai plus en profondeur plus tard dans la journĂ©e.

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

@jansedlon comme dit plus tĂŽt, nous travaillons sur quelque chose Ă  ce sujet qui n'est pas couvert dans le blog de @ivan-kleshnin. J'espĂšre pouvoir partager plus Ă  ce sujet trĂšs bientĂŽt.

@timneutkens J'adore les changements jusqu'Ă  prĂ©sent 🙏 Avez-vous l'intention d'amĂ©liorer/prendre en charge la statique+internationalisation complĂšte ?

Nous avons utilisé les nouvelles API getStaticProps / getStaticPaths dans notre migration de tinacms.org de Gatsby vers Next.js, et jusqu'à présent, c'est génial !

Une pierre d'achoppement que nous avons eue est la génération d'un flux RSS. Idéalement, nous aimerions le générer de maniÚre statique, car le contenu auquel il fait référence est généré de maniÚre statique. Je ne vois pas de moyen de le faire actuellement, donc à la place, nous le gérons simplement cÎté serveur en interrogeant le contenu et en écrivant XML dans la réponse.

Y a-t-il eu des discussions sur la prise en charge de la génération statique pour les types de contenu non HTML ?

Pour info, nous avons commencé à utiliser getStaticProps sur zeit maintenant et les versions en utilisant le drapeau --prod et le cache n'était pas vidé pour les fichiers json sur les nouvelles versions. Le retour de notre version de production à l'utilisation de la fonction d'alias a fonctionné et le cache a été vidé.

Nous avons utilisé les nouvelles API getStaticProps / getStaticPaths dans notre migration de tinacms.org de Gatsby vers Next.js, et jusqu'à présent, c'est génial !

Une pierre d'achoppement que nous avons eue est la génération d'un flux RSS. Idéalement, nous aimerions le générer de maniÚre statique, car le contenu auquel il fait référence est généré de maniÚre statique. Je ne vois pas de moyen de le faire actuellement, donc à la place, nous le gérons simplement cÎté serveur en interrogeant le contenu et en écrivant XML dans la réponse.

Y a-t-il eu des discussions sur la prise en charge de la génération statique pour les types de contenu non HTML ?

J'y pensais par moi-mĂȘme et je viens de dĂ©couvrir ça. Voici mes scripts :

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

Avant next build est appelĂ© yarn sitemap qui gĂ©nĂšre statiquement le plan du site. Vous pouvez utiliser la mĂȘme technique, pour mettre en cache toutes les donnĂ©es sur json par exemple, dont vous aurez besoin dans getStaticProps et vous pouvez les rĂ©utiliser sur plusieurs pages.

Mise Ă  jour de la RFC, modification un peu du comportement de getStaticPaths (vous devez retourner une clĂ© paths maintenant, cela reflĂšte getStaticProps oĂč props doivent ĂȘtre retournĂ©s. Ceci le changement n'a pas encore atterri dans Next.js.

Ajout d'une explication sur le comportement de fallback (génération en arriÚre-plan à la demande de pages qui n'ont pas été exportées au moment de la construction).

A fait une autre mise à jour de la RFC, a ajouté une explication des changements dans la navigation client en ce qui concerne un état Loading .

Nous pourrions vouloir ajouter un moyen pour les utilisateurs de savoir si l'Ă©tat de chargement est rendu via un crochet React đŸ€”

Super trucs ! Je me demandais simplement s'il y aurait un moyen pour les pages générées de maniÚre statique de partager des données entre plusieurs routes à l'aide d'un seul fichier JSON (comme le fractionnement de code mais pour les données) ?

Je suis tombé sur la derniÚre version de canary et j'ai immédiatement été mordu par le nouvel état Loading . Dans le passé, il était agréable de supposer en toute sécurité que j'avais déjà les bonnes données avant que la couche de vue ne commence le rendu. Le chargement asynchrone forcé est un grand écart par rapport à cela. J'ai vraiment aimé extraire tous les points de terminaison standard que les nouveaux points de terminaison SSR générés automatiquement remplaceront, mais je n'avais pas l'intention de reconcevoir chaque page pour inclure de nouveaux états Loading .

Je comprends le dĂ©sir d'un TTFB plus rapide, et Ă  l'avenir, cela pourrait ĂȘtre un plus pour mon application. Mais serait-il possible de faire de l'Ă©tat Loading une fonctionnalitĂ© d' activation ou de dĂ©sactivation , similaire Ă  la fallback: false pour getStaticPaths ? Peut-ĂȘtre un export const enableLoadingState = false sur la page, ou Ă  l'Ă©chelle du site dans le next.config.js .

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

Encore une fois, un rappel que vous utilisez une fonctionnalité expérimentale et que nous expérimentons actuellement le comportement.

J'ai déployé mon site Web SSG (expérimental) sur Now (en utilisant une configuration par défaut). Cela fonctionne bien, mais je vois des erreurs 404 dans l'onglet réseau lors de la navigation sur le site. Toutes les erreurs 404 pointent vers _next/static/pages/[slug].js .

Est-ce que ce comportement est attendu alors qu'il est expérimental ? Ou dois-je modifier certains paramÚtres ?

@joostmeijles, il semble que vous ne fournissiez pas les bons href et as Ă  next/link . Pour les pages dynamiques, href doit ĂȘtre la page href='/[slug]' et as doit ĂȘtre l'URL as='/slug-1'

J'obtiens 3 journaux dans la console pendant la construction, est-ce un bug ?

// 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" } },
        ]
    }
}

Non, c'est prévu selon fallback dans le RFC.

Non, c'est prévu selon fallback dans le RFC.

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" } },
        ]
    }
}

J'ai essayé de me désabonner mais j'obtiens cette erreur.

Erreur : clés supplémentaires renvoyées par unstable_getStaticPaths dans /[year] (fallback) Le seul champ autorisé actuellement est paths

Encore une fois, rappelez-vous que vous utilisez une fonctionnalité expérimentale et que nous expérimentons actuellement le comportement et que tout n'est pas implémenté.

Cette fonctionnalité getStaticProps ne sera-t-elle disponible que pour les pages ?
Serait-il également intéressant pour l'application/le document, par exemple, récupérer une configuration globale pour l'application ?

J'ai « avec succĂšs » mis en Ɠuvre cela et je suis satisfait des rĂ©sultats jusqu'Ă  prĂ©sent.. mais je me demande s'il existe un moyen de rendre les versions ultĂ©rieures «plus rapides»? Par exemple, vĂ©rifiez si les pages gĂ©nĂ©rĂ©es par SSG n'ont pas changĂ© et ne les rĂ©gĂ©nĂ©rez pas ? (Probablement un vƓu pieux de ma part)

@timneutkens Avez-vous l'intention d'ajouter un gĂ©nĂ©rateur sitemap.xml pour les pages SSG ? Je ne parle mĂȘme pas de routes dynamiques car je pense qu'il est plus facile de l'implĂ©menter uniquement pour les pages statiques pour le moment.

@timneutkens Avez-vous l'intention d'ajouter un gĂ©nĂ©rateur sitemap.xml pour les pages SSG ? Je ne parle mĂȘme pas de routes dynamiques car je pense qu'il est plus facile de l'implĂ©menter uniquement pour les pages statiques pour le moment.

Oui, ce serait une excellente option. Je gĂ©nĂšre actuellement un moi-mĂȘme avec SSR. (mais le fichier sitemap.xml est long Ă  charger)

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

Initialement uniquement pour les pages, car d'autres travaux auront un impact sur getStaticProps aprĂšs son atterrissage.

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

Oui mais pas dans le cadre de cette RFC. Il y aura un suivi aprĂšs cet atterrissage.

@timneutkens Je pense que l'implémentation des pages SSG est facile car vous pouvez pousser un URI dans un tableau à chaque fois que Next crée une page statique, puis, quand elle se termine, mappez simplement le tableau dans chaque balise XML, joignez-le et insérez-le au milieu d'une balise <sitemapindex> . Le getStaticProps pourrait avoir une autre clé dans l'objet de retour nommée excludeFromSitemap donc la valeur par défaut serait que toutes les pages soient incluses dans le sitemap.xml mais avec une option de désinscription.

Si tel Ă©tait le cas, les dĂ©veloppeurs auraient un contrĂŽle prĂ©cis sur quelle page statique irait dans le plan du site (par exemple: si la page [foo] de » getStaticPaths fonction des chemins est revenu avec foo params 'abc' et 'xyz' mais seul le fichier 'abc' devrait ĂȘtre dans le plan du site, le dĂ©veloppeur pourrait dĂ©finir excludeFromSitemap Ă  true si le paramĂštre ==='xyz' dans getStaticProps .

De plus, pour les pages SSR et statiques, il pourrait ĂȘtre possible d'exporter une constante (c'est-Ă -dire export const excludeFromSitemap = true; ) Ă  partir du fichier de page, tout comme getServerProps , getStaticPaths et getStaticProps sont exportĂ©s.

Dans les pages SSG, s'il existe une constante excludeFromSitemap exportée (page par défaut) et que cette clé est également dans l'objet renvoyé par la fonction getStaticProps (spécifique au chemin), la valeur exportée doit agir par défaut valeur pour tous les chemins de cette page et le chemin spécifique excludeFromSitemap , lorsqu'il est présent dans l'objet getStaticProps , devrait remplacer la valeur par défaut de la page (ainsi une page pourrait faire export cosnt excludeFromSitemap = true puis ajoutez la clé excludeFromSitemap à l'objet renvoyé par getStaticProps avec la valeur false pour exclure tous les chemins du plan du site à l'exception de celui-ci).

Le code d'ajout au tableau ressemblerait à ceci (j'ai calculé la table de vérité et obtenu l'expression booléenne minimale avec une carte de Karnaugh):

//...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);

Transformer le tableau en plan du site serait aussi simple que de le faire (en supposant que les URI du tableau sont déjà encodés et filtrés par !excludeFromSitemap ):

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

Je pense que cette fonctionnalitĂ© s'intĂ©grerait bien dans Next.JS car une partie de sa mission est de donner aux utilisateurs le score de 100 SEO et avoir un sitemap.xml aiderait grandement! ( robots.txt pourraient Ă©galement ĂȘtre gĂ©nĂ©rĂ©s en ajoutant un else Ă  la condition qui ajoute les chemins au tableau sitemap pour ajouter ce chemin dans un autre tableau de pages non autorisĂ©es)

Dans la version actuelle, lorsque vous utilisez la fonction unstable_getStaticPaths avec la fonction unstable_getStaticProps , vous ne pouvez pas faire d'appels API aux fonctions résidant dans /api/ .
Comme le serveur n'est pas en cours d'exĂ©cution, il est impossible de faire les requĂȘtes correspondantes et de gĂ©nĂ©rer les props statiques de cette façon.
Vous devez soit ne pas fournir les fonctions des chemins (ce qui rend ce SSR avec un cache, ce qui est quand mĂȘme bien !), soit vous fier au SSR au lieu du SSG.

Peut-ĂȘtre que ce serait un bon ajout pour cette fonctionnalitĂ©? Je ne sais pas quel serait le meilleur moyen ici, j'ai lu une proposition ailleurs, qui suggĂ©rait de raccourcir la requĂȘte http, avec des routes SSR et /api , cela serait Ă©galement utile ici.

Mais tout cela impliquerait bien sĂ»r d'exĂ©cuter du code dans l'environnement de construction, ce qui ferait des appels Ă  d'autres services / appels db ou similaires. Cela devrait ĂȘtre prĂ©cisĂ© lors de la mise en Ɠuvre, mais ce serait un ajout intĂ©ressant pour cette fonctionnalitĂ©.

@reckter Oui, je viens de faire quelque chose de similaire moi-mĂȘme. Je devais me connecter Ă  ma base de donnĂ©es pour chaque demande de page distincte pendant qu'elles Ă©taient gĂ©nĂ©rĂ©es de maniĂšre statique. C'Ă©tait trĂšs Ă©trange...

J'espĂšre que ce n'est pas le cas d'utilisation final

Ce serait bien d'avoir une sorte de script d'initialisation que vous pouvez configurer Ă  partir du next.config ou quelque chose ...

@reckter Un moyen de raccourcir les requĂȘtes HTTP vers les routes API de SSG/SSR serait tellement bien ! C'est Ă©trange de me faire une demande de rĂ©seau dans l'un ou l'autre de ces scĂ©narios.

Quoi qu'il en soit, une solution possible pour accéder aux routes API pendant SSG serait d'avoir un serveur local exécutant uniquement les routes /api avant de compiler les pages statiques ! Les étapes de construction seraient donc :

  1. Lancer un serveur (peut-ĂȘtre appelĂ© "serveur de compilation api" ou quelque chose comme ça) ne servant que les routes /api
  2. Courir unstable_getStaticPaths
  3. Courir unstable_getStaticProps
  4. Compiler les pages statiques

@reckter fondamentalement, vous n'avez pas besoin d'appeler des routes API, vous pouvez appeler la fonction qu'elle implémente directement, cela évite également une grande partie de la surcharge liée aux causes http.

Fondamentalement, si vous avez actuellement une route API qui ressemble à ceci :

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

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

Vous le changeriez en :

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)
}

Et puis dans votre page :

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

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

Il serait difficile de faire de mĂȘme pour les API GraphQL. Et aussi pour la plupart des REST.

Appel API != récupération depuis la base de données (en général)
Il y a presque toujours une logique métier dans la couche API, comme le renommage des champs, le reformatage des données, etc.

Je suis sûr que vous avez des raisons d'interdire les appels pages/api ... mais le contournement de la vraie API ne sera ni facile ni bon marché. Et quelques millisecondes épargnées ne l'emporteront pas sur les frais supplémentaires de code/complexité IMO.

Il semble Ă©galement Ă©trange que les demandes Ă  n'importe quelle API soient autorisĂ©es. Sauf le tien đŸ€·â€â™‚

l'utilisation de unstable_getStaticPaths provoque le rechargement de la page, perdant l'état actuel dans le redux par exemple. Ce comportement sera-t-il modifié à l'avenir ?

edit : il semble que ce comportement puisse ĂȘtre contournĂ© en utilisant l'option as dans les liens ou le routeur

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

@meesvandongen c'Ă©tait toujours comme ça. Si votre <Link> n'est pas valide, cela vous amĂšne Ă  la partie backend, fonctionnant essentiellement comme un <a> . Les fragments dynamiques tels que [key] doivent ĂȘtre associĂ©s aux valeurs correspondantes.

@reaktivo pages/[lang]/blog/[id].js -> dans getStaticPaths fournit toutes les URL Ă  rendre statiquement.

https://github.com/zeit/next.js/issues/9524#issuecomment-562625858
dans ce cas, il doit ajouter la fonction getStaticPaths et getStaticProps pour chaque page sauf index.js.
S'il y a des pages mdx, le projet est plus difficile Ă  maintenir

envisager de changer ou de devenir compatible avec les méthodes statiques getStaticPaths getStaticProps . https://github.com/zeit/next.js/issues/9524#issuecomment -558617056
Si tel est le cas, la page peut ĂȘtre encapsulĂ©e par une fonction d'ordre supĂ©rieur ou un composant d'ordre supĂ©rieur HOC.
De cette façon, le code est plus maintenable et plus pratique pour les typesscript.


tremblement d'arbre vs dynamique. Quel compromis casse-tĂȘte.😂

Avec 9.2.3-canary.13 j'ai essayé d'utiliser fallback: false dans getStaticPaths comme ceci :

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

mais il Ă©choue avec l'erreur suivante :

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

Avec 9.2.3-canary.13 j'ai essayé d'utiliser fallback: false dans getStaticPaths comme ceci :

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

mais il Ă©choue avec l'erreur suivante :

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

Je pense que vous avez besoin de la carte à un niveau supérieur, donc la carte renvoie l'objet que vous avez actuellement, mais avec un slug unique. au lieu de mapper dans les chemins.

Je n'ai pas encore mis Ă  jour ma version sur nextjs, mais cela devrait ĂȘtre similaire :

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

@jorngeorg c'est un PR ouvert : https://github.com/zeit/next.js/pull/10701

Contribution fantastique! Cela améliore vraiment le processus de rendu statique.

Je recommande d'ajouter Ă  la documentation que sur les routes dynamiques, le "fallback" sera gĂ©nĂ©rĂ© sans aucun appel Ă  getStaticProps - ce qui signifie que vous devez coder votre composant pour tenir compte du cas oĂč les props sont vides.

Vous pouvez également modifier le comportement pour appeler getStaticProps sans contexte lors de la création du repli. Cela serait cohérent avec le fonctionnement actuel de next export (par exemple, /p/[id].js est exporté vers /p/[id].html en exécutant son getInitialProps sans contexte).

  • getStaticProps - Opt-in Ă  la gĂ©nĂ©ration statique (SSG) Ă  next build time.
  • getServerProps - Optez pour le rendu cĂŽtĂ© serveur (SSR) qui rend Ă  la demande.

10722

Renommez getServerProps en getServerSideProps.

Je recommande d'ajouter Ă  la documentation que sur les routes dynamiques, le "fallback" sera gĂ©nĂ©rĂ© sans aucun appel Ă  getStaticProps - ce qui signifie que vous devez coder votre composant pour tenir compte du cas oĂč les props sont vides.

C'est bien de le mentionner ! J'ai également eu des erreurs de construction/déploiement parce que j'ai raté cela.

Mise à jour de la RFC pour refléter les changements

@timneutkens

  • Une demande ultĂ©rieure au mĂȘme chemin servira la page gĂ©nĂ©rĂ©e

Je suppose que cela signifie que Next.js mettra en cache la page générée ? Est-ce un cache en mémoire ? Ce cache est-il limité par des limites ou cela peut-il entraßner des fuites de mémoire ?

Lorsque vous utilisez next start il utilise lru-cache similaire à l'exemple de mise en cache actuel, actuellement la limite par défaut est de 50 Mo, nous pourrions le rendre configurable plus tard : https://github.com/zeit/next.js/ blob/canary/packages/next/next-server/server/spr-cache.ts#L90

Lorsque vous hébergez sur ZEIT Maintenant, la génération et la mise en cache se produisent sur le CDN/Proxy, donc cela fonctionne légÚrement différemment et vous n'avez jamais à vous soucier des fuites de mémoire ou si vous dépassez la limite lru.

ok, ça semble raisonnable. C'est plus ou moins ce que j'avais en tĂȘte comme comportement par dĂ©faut sensĂ©.

  • getStaticProps - Opt-in Ă  la gĂ©nĂ©ration statique (SSG) Ă  next build time.
  • getServerProps - Optez pour le rendu cĂŽtĂ© serveur (SSR) qui rend Ă  la demande.

10722

Renommez getServerProps en getServerSideProps.

Pourquoi le renommer ? IMHO getServerProps est suffisamment précis et plus court à taper, l'ajout de Side me semble redondant.

Je me demandais s'il y avait des modifications apportées à la méthode getStaticPaths ? Mes pages dynamiques ne sont plus générées en tant que pages statiques, elles sont désormais exportées en tant que fonctions lambda ?

Ai-je raison lorsque le comportement par défaut est maintenant que les pages sont d'abord rendues en lambda et qu'aprÚs avoir visité une page spécifique, la page est générée en une page statique ? (comme mentionné dans le fallback)

@erhankaradeniz Aucune modification n'a été apportée à getStaticPaths qui aurait pour effet que vos pages soient Lambdas. Il s'agit probablement d'une erreur d'utilisation.

Pouvez-vous s'il vous plaĂźt montrer votre code afin que nous puissions identifier le problĂšme?

@Timer pour l'instant, je suis revenu Ă  [email protected] oĂč je peux toujours utiliser des paramĂštres, jusqu'Ă  ce que je

voici comment j'ai actuellement généré mes chemins:

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

et dans une autre page je fais :

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

n'ont pas rĂ©ussi Ă  le convertir vers la nouvelle version de Canary avec les chemins. Je dois faire quelque chose de mal, car console.logs ne sont mĂȘme pas dĂ©clenchĂ©s dans les getStaticPath

J'ai des problÚmes avec le pré-rendu des chemins imbriqués et 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("/"),
        }
      }
    }),
  }
}

mĂšne Ă 

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.

pour la page d'accueil. Pour une raison quelconque, NextJS ne correspond pas

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

Ă 

/[lang]/[...slugs]

Si je fournis {lang: "en", slugs: ["/"]} il se construit mais avec une mauvaise URL :

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

Pour mémoire, getServerSideProps fonctionne trÚs bien avec une configuration similaire.

Je sais que c'est expérimental mais ce fil est pour donner des commentaires, non?

pages/[lang]/[...slugs].js correspond à /en/abcdef et non à /en , pour cela vous devez actuellement créer pages/[lang]/index.js .

Une demande de fonctionnalité est ouverte pour cela : https://github.com/zeit/next.js/issues/10488

Tout d'abord, c'est génial. J'espérais avoir quelque chose comme ça dans Next.js pour pouvoir enfin m'éloigner de Gatsby.js et avoir une application hybride (statique + dynamique).

🚀 J'ai essayĂ© la version complexe de l'application canari et Ă  moitiĂ© cuite qui a bien fonctionnĂ©. J'avoue que je n'ai pas lu tous les commentaires ici, mais je ne sais pas si le tree-shaking est encore mis en Ɠuvre.

đŸ€” getStaticPaths ressemble beaucoup plus Ă  setStaticPaths oĂč nous dĂ©finissons le chemin statique pour le comportement SSG. Ce genre de me dĂ©routĂ© un peu.

🧐 Je me demande si nous pouvons amĂ©liorer les temps de construction en ayant des catĂ©gories de construction ? Je sais que cela compliquerait la configuration, mais cela en vaudra la peine. Laissez-moi expliquer:

Que faire si nous avons quelque chose comme setBuildCategory qui le dĂ©finit sur blog ou pages ou tout ce que quelqu'un veut 2020-content . Ensuite, le gĂ©nĂ©rateur SSG recherche la catĂ©gorie de la page qui a Ă©tĂ© modifiĂ©e et essaie uniquement de reconstruire cette catĂ©gorie Ă  partir d'une combinaison de cache + nouveau rendu. Quelque chose comme ça peut nous aider Ă  rendre SSG rapide et Ă  Ă©viter des temps de construction Ă©normes pour des choses qui ne sont pas sujettes Ă  beaucoup de changements mais qui pourraient encore changer et qui ne peuvent donc pas ĂȘtre archivĂ©es.

Si cela a du sens ; Je suis heureux de sauter sur un appel et de discuter à ce sujet.

Comment gérer getServerSideProps avec une implémentation de serveur personnalisée ?

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

Dans l'exemple ci-dessus, la visite de /a affichera la page pages/b.js . Mais une redirection cÎté client vers /a tente de télécharger le fichier a.json , ce qui n'existe pas dans ce cas.

Sommes-nous censĂ©s avoir des conditions similaires pour les requĂȘtes Ă  /_next/data/{BUILD_ID}/{PAGE}.json pour rendre diffĂ©rents fichiers JSON ?

Pour utiliser fallback: true dans getStaticPaths, comment obtenir l'objet req ? Il semble actuellement que je ne peux pas. La raison pour laquelle j'en ai besoin est de récupérer des cookies dans le navigateur pour authentifier un itinéraire

@tylermcrobert comment imaginez-vous saisir des cookies quand il n'y a aucune demande ?!
Les routes avec un backend dĂ©pendant de demandes rĂ©elles de visiteurs ne peuvent pas ĂȘtre rendues statiques par les dĂ©finitions de "statique" et "dynamique". Cela ne veut pas dire que vous ne pouvez pas combiner static et auth... c'est juste que la partie auth appartiendra Ă  l'API et au code client au lieu des pages.

Comment gérer getServerSideProps avec une implémentation de serveur personnalisée ?

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

Dans l'exemple ci-dessus, la visite de /a affichera la page pages/b.js . Mais une redirection cÎté client vers /a tente de télécharger le fichier a.json , ce qui n'existe pas dans ce cas.

Sommes-nous censĂ©s avoir des conditions similaires pour les requĂȘtes Ă  /_next/data/{BUILD_ID}/{PAGE}.json pour rendre diffĂ©rents fichiers JSON ?

Next.js prend en charge les paramÚtres de route dynamiques, donc le remappage dans un serveur personnalisé est rarement nécessaire : https://nextjs.org/docs/routing/dynamic-routes

L'approche que vous avez déjà décrite ne fonctionne pas avec <Link> (cela entraßnerait une transition de pleine page), donc getServerSideProps fonctionne déjà.

@tylermcrobert comment imaginez-vous saisir des cookies quand il n'y a aucune demande ?!
Les routes avec un backend dĂ©pendant de demandes rĂ©elles de visiteurs ne peuvent pas ĂȘtre rendues statiques par les dĂ©finitions de "statique" et "dynamique". Cela ne veut pas dire que vous ne pouvez pas combiner static et auth... c'est juste que la partie auth appartiendra Ă  l'API et au code client au lieu des pages.

Peut-ĂȘtre que je comprends mal l'option de secours dans ce cas. Ce que vous dites a tout Ă  fait du sens dans le contexte du temps de construction.

N'est-ce pas fallback: true quand il n'y a pas d'itinéraire prédéfini ? Dans ce cas, un fallback serait atteint depuis le navigateur, non ?

@tylermcrobert oui fallback: true case a une requĂȘte mais l'API doit ĂȘtre unifiĂ©e par le "plus petit dĂ©nominateur commun". Je ne peux pas imaginer un systĂšme de travail oĂč tout est construit avec un ensemble de locaux, puis il est progressivement mis Ă  jour avec un ensemble de locaux totalement diffĂ©rent. Ce sera une catastrophe Ă  soutenir.

Je pense que vous manquez le point que ces builds incrémentiels seront toujours mis en cache entre les builds. Ainsi le rÎle du premier visiteur va influencer le résultat de build pour tous les utilisateurs conséquents ! Cela ressemble à une mauvaise idée.

@ivan-kleshnin Je comprends et je suis certainement d'accord. La raison pour laquelle je demande est à cause de mon cas d'utilisation spécifique.

J'utilise un CMS sans tĂȘte qui permet la prĂ©visualisation des fonctionnalitĂ©s afin que les pages qui devront ĂȘtre prĂ©visualisĂ©es ne soient pas incluses au moment de la construction (parce que l'entrĂ©e en prĂ©visualisation n'aura pas existĂ© Ă  ce stade). J'ai pensĂ© que c'Ă©tait un cas oĂč l'option de secours entrerait en jeu.

Pour accéder à cet aperçu, j'ai besoin d'accéder à la référence d'aperçu de l'API qui est donnée via un cookie.

Est-ce un cas oĂč je devrais simplement supprimer complĂštement useStaticProps ? Je dĂ©testerais perdre le bĂ©nĂ©fice des versions statiques car je ne peux pas prĂ©visualiser mes documents.

L'attrait de cette RFC par rapport Ă  quelque chose comme Gatsby est qu'elle nous donne un "contrĂŽle hybride" avec une gĂ©nĂ©ration de site statique qui rend moins pĂ©nible le travail avec des CMS sans tĂȘte.

J'utilise un CMS sans tĂȘte qui permet la prĂ©visualisation des fonctionnalitĂ©s afin que les pages qui devront ĂȘtre prĂ©visualisĂ©es ne soient pas incluses au moment de la construction (parce que l'entrĂ©e en prĂ©visualisation n'aura pas existĂ© Ă  ce stade). J'ai pensĂ© que c'Ă©tait un cas oĂč l'option de secours entrerait en jeu.

Restez connectés, plus bientÎt

Donc, si je comprends bien, nous pouvons utiliser fallback true lorsque, par exemple, dans mon cas, un utilisateur s'enregistre (aucune page statique n'est générée car il s'agit d'une nouvelle page/utilisateur) mais lorsque le profil reçoit une visite, il est généré automatiquement ?

Erhan Karadeniz
http://www.erhankaradeniz.com

Le 4 mars 2020, Ă  20h25, Tim Neutkens [email protected] a Ă©crit :


J'utilise un CMS sans tĂȘte qui permet la prĂ©visualisation des fonctionnalitĂ©s afin que les pages qui devront ĂȘtre prĂ©visualisĂ©es ne soient pas incluses au moment de la construction (parce que l'entrĂ©e en prĂ©visualisation n'aura pas existĂ© Ă  ce stade). J'ai pensĂ© que c'Ă©tait un cas oĂč l'option de secours entrerait en jeu.

Restez connectés, plus bientÎt

-
Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail, consultez-le sur GitHub ou désabonnez-vous.

Les donnĂ©es utilisateur sont un mauvais exemple car vous voudriez rĂ©cupĂ©rer ce cĂŽtĂ© client. Le repli est lĂ  pour les pages gĂ©nĂ©rant statiquement Ă  la demande qui n'ont pas Ă©tĂ© gĂ©nĂ©rĂ©es au moment de la construction. Par exemple, vous voudrez peut-ĂȘtre gĂ©nĂ©rer les 100 meilleurs articles de blog au moment de la crĂ©ation et ne pas en gĂ©nĂ©rer d'autres avec moins de trafic.

Des documents seront bientĂŽt disponibles pour cela.

Ouais, ce que je voulais dire, c'était une page d'espace réservé .. Je récupérerais effectivement les données utilisateur cÎté client.

@timneutkens Y aura-t-il un moyen de supprimer ou de reconstruire des pages spécifiques générées statiquement ?

Salut!!! Sonne comme l'application optimale. J'aime à la fois React et Next !!! A rendu tout si élégant et simple pour nous à utiliser !! Mais l'exemple inclut la notion de blog. J'aimerais voir un exemple d'implémentation lors de l'interrogation d'un CMS Headless et effectuer la recherche par page/post en tant qu'exportation en tant qu'élément statique.

// bravo, car c'est bientĂŽt vendredi !!!

@timneutkens c'est excitant

Un scénario que nous rencontrons fréquemment et je n'ai pas encore de solution parfaite avec next.js ou gatsby, à l'exception des routes dynamiques ou de la génération de projets en boucle :

Pour des raisons historiques, nous devons gĂ©rer plusieurs domaines (et il n'y a aucune envie de changer cela) qui servent les mĂȘmes pages/exactes Ă  l'exception des prix, de la devise, des numĂ©ros de tĂ©lĂ©phone d'assistance et des sĂ©lecteurs de langue. Par nature, la plupart de ces pages marketing sont assez statiques et il suffirait de les crĂ©er quotidiennement ou hebdomadairement (au lieu de les rendre Ă  chaque demande).

Ma question/pensĂ©e : voyez-vous un moyen (Ă  l'avenir ?) Le getStaticPaths pourrait gĂ©nĂ©rer des pages basĂ©es sur quelque chose qui n'est pas un paramĂštre de route mais qui pourrait ĂȘtre utilisĂ© au niveau de la requĂȘte pour basculer entre eux (par exemple sans serveur la fonction renvoie un rĂ©sultat statique prĂ©dĂ©fini basĂ© sur locale )

ConcrĂštement, cela signifierait que https://mysite.com/my-product et https://mysite.co.uk/my-product serviraient deux pages statiques diffĂ©rentes, mais sans que nous ayons Ă  gĂ©nĂ©rer notre prochaine application 50 fois ou Ă  frapper un CMS Ă  chaque demande😅

Merci d'avance et impatient d'entendre vos pensĂ©es, surtout si c'est quelque chose pour l'avenir qui pourrait ĂȘtre rĂ©solu / contournĂ© ❀

Je pense à un cas d'utilisation dans lequel je souhaite utiliser SSG pour les pages de destination à fort trafic pour le référencement et pour réduire la charge du serveur, mais je souhaite toujours que les données actuelles soient utilisées aprÚs l'hydratation et le routage cÎté client vers cette page. Cela serait-il possible?

Donc, fondamentalement, du cĂŽtĂ© du routage cĂŽtĂ© client vers cette page, le comportement devrait ressembler Ă  getInitialProps (les donnĂ©es actuelles sont rĂ©cupĂ©rĂ©es avant que la page ne devienne visible). Et sur le routage cĂŽtĂ© serveur vers cette page, le html statique doit ĂȘtre servi et hydratĂ©, puis (Ă©ventuellement) certaines rĂ©ponses API rĂ©cupĂ©rĂ©es pour mettre Ă  jour certaines donnĂ©es sur la page.

Je viens de jouer avec unstable_getStaticProps juste pour l'essayer et je suis tombé sur un conflit amusant : il est difficile d'utiliser des routes API avec getStaticProps .

Ne faites pas attention à la sémantique du code, mais uniquement au flux de récupération des données :

// 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())
    },
  };
}

La construction de la page se bloquera au moment de la construction car le serveur n'est pas en cours d'exĂ©cution. Je ne sais pas s'il s'agit d'un cas d'utilisation valide, car getStaticProps ne doit pas ĂȘtre utilisĂ© avec quelque chose de trop dynamique, mais j'ai pensĂ© que c'Ă©tait un cas intĂ©ressant Ă  partager (je peux tout Ă  fait imaginer un point de terminaison d'API Route chargĂ© d'obtenir donnĂ©es d'une autre API et reformatez-les.

@martpie Vous voudrez peut-ĂȘtre consulter ce commentaire : https://github.com/zeit/next.js/issues/9524#issuecomment -589772756

La prise en charge de la génération de site statique (SSG) de nouvelle génération est désormais stable dans Next.js 9.3 !

Cette version inclut également la prise en charge du "Mode Aperçu", ou la possibilité de contourner la page statiquement pré-rendue et de rendre la page à la demande pour les utilisateurs autorisés .

Vous pouvez en savoir plus Ă  ce sujet dans notre article de blog . Si vous ĂȘtes plus pratique, plongez directement dans nos docs !

Veuillez poster vos questions à la communauté Next.js GitHub !

C'est trop cool! Merci pour le dur travail!

Cette nouvelle fonctionnalité ne semble pas fonctionner avec saga et redux maintenant

Cette page vous a été utile?
0 / 5 - 0 notes