Next.js: Mejoras de generación estática / SSG

Creado en 25 nov. 2019  ·  250Comentarios  ·  Fuente: vercel/next.js

Resumen

Permita que Next.js se vuelva completamente híbrido al proporcionar métodos para realizar tanto la generación estática como la representación del lado del servidor por página.

  • Dos nuevos métodos de obtención de datos por página

    • getStaticProps - Optar por la generación estática (SSG) en next build tiempo.

    • getServerSideProps - Optar por el renderizado del lado del servidor (SSR) que renderiza bajo demanda.

  • Un nuevo método para generar estáticamente (SSG) un conjunto de rutas a partir de fuentes dinámicas

    • getStaticPaths - Lista de retorno de parámetros para rutas dinámicas para generar generación estática (SSG)

Este RFC analiza exclusivamente las adiciones de API. Toda la nueva funcionalidad es completamente compatible con versiones anteriores y se puede adoptar gradualmente. Esta RFC no presenta desaprobaciones.

Fondo

Al crear sitios web o aplicaciones web, generalmente debe elegir entre 2 estrategias: generación estática (SSG) o renderización del lado del servidor (SSR).

Next.js, en cambio, le permite crear aplicaciones híbridas que le permiten elegir la estrategia que se utiliza por página. A partir de Next.js 9, las páginas sin getInitialProps se optimizan estáticamente y se generan como archivos .html en next build .

Sin embargo, es posible que desee realizar la búsqueda de datos mientras genera páginas estáticas para su caso de uso específico.

Por ejemplo, para generar estáticamente páginas de marketing desde un CMS o una sección de blog del sitio.

El uso de getInitialProps lo optaría por SSR en ese caso.

Next.js tiene actualmente un comando next export , que hace que la aplicación sea completamente SSG, perdiendo la naturaleza híbrida de Next.js.

Si usa next export con getInitialProps surge otro problema. getInitialProps se llama en el momento de la compilación (lo cual es genial), pero luego, cuando usa next/link para moverse entre las páginas, getInitialProps se llama del lado del cliente, en lugar de usar next export Resultado de

Esto también significa que la fuente de datos (punto final CMS / API) se llama directamente en las transiciones del lado del cliente, si su fuente de datos está inactiva, las transiciones del lado del cliente se interrumpen al moverse entre páginas.

Hemos colaborado con grandes usuarios de SSG y next export en Next.js como HashiCorp (gracias @jescalan) e investigamos exhaustivamente las restricciones correctas para introducir dos nuevos métodos de obtención de datos: getStaticProps y getServerSideProps . Pero también una forma de proporcionar parámetros para generar páginas estáticas para rutas dinámicas: getStaticPaths (reemplazo de exportPathMap que es por página).

Estos nuevos métodos tienen muchas ventajas sobre el modelo getInitialProps , ya que existe una clara distinción entre lo que se convertirá en SSG y SSR.

  • getStaticProps marca la página para que se genere estáticamente en el momento de la compilación (cuando se ejecuta next build )
  • getStaticPaths permite devolver una lista de parámetros para generar en el momento de la construcción para rutas dinámicas
  • getServerSideProps marca la página para que se muestre en el lado del servidor en cada solicitud y es la más similar al comportamiento actual de getInitialProps cuando se usa un servidor.

Separar estos métodos también nos permite proporcionar el objeto de contexto correcto que se puede escribir con TypeScript. Cuando opta por una estrategia de representación específica, obtiene los valores correctos, actualmente con getInitialProps debe adivinar qué está disponible en SSG vs SSR cuando se usa TypeScript.

Además, al hacer explícitos estos métodos, nos permitirá documentar las diferentes compensaciones con mayor claridad.

Implementación

Tenga en cuenta que todos estos métodos son de nivel superior en el archivo de componentes de la página y no se pueden anidar, similar a getInitialProps .

getStaticProps

El uso de getStaticProps significa que la página se representará estáticamente en el momento de la compilación (SSG).

Este nuevo método le permitirá buscar datos para una página que se generará estáticamente en un archivo .html en next build tiempo.

Next.js también generará automáticamente un archivo JSON que contiene el resultado de getStaticProps en next build time. Esto se está utilizando para el enrutamiento del lado del cliente.

Cuando el enrutamiento del lado del cliente a través de next/link o next/router , Next.js obtendrá este archivo JSON para obtener los accesorios necesarios para representar la página del lado del cliente.

Las propiedades se devuelven bajo una clave props para que se puedan introducir otras opciones en el futuro.

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

El context contendrá:

  • params - Los parámetros en una ruta dinámica.

getStaticPaths

Esta es una extensión del uso de getStaticProps para rutas dinámicas.

getStaticPaths reemplaza la necesidad de tener un exportPathMap y funciona por página.

Dado que es posible que desee generar estáticamente una lista de URL que tienen un parámetro dinámico, como en el ejemplo siguiente, un slug . Next.js proporcionará un método getStaticPaths que permite devolver una lista de URL. Dado que es un método async , también puede obtener esa lista de una fuente de datos como su 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" } }
    ]
  };
}

Retroceder

En muchos casos, es posible que no desee renderizar previamente todas las rutas posibles en su aplicación en el momento de la compilación (por ejemplo, si tiene millones de productos). Por esta razón, Next.js generará automáticamente una página fallback que es una representación de la página sin datos (para que se pueda mostrar un estado de carga) para cuando la página aún no se haya generado.

El comportamiento exacto de servir será:

  • Solicitud entrante

    • Next.js comprueba si la ruta se generó en el momento de la compilación

    • Si la ruta fue generada



      • servir directamente



    • Si la ruta no se generó



      • Sirva el respaldo


      • Next.js renderiza la página (con datos) en segundo plano y la agrega a la lista de páginas generadas


      • La solicitud posterior a la misma ruta servirá la página generada


      • Esto garantiza que los usuarios siempre tengan una experiencia rápida y nunca tengan un TTFB lento debido a la representación del servidor, al tiempo que se preservan las compilaciones rápidas y las propiedades de generación estática.



En caso de que desee que las rutas que no se generaron en el momento de la compilación den como resultado un 404, también es posible devolver fallback: false 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

Cuando se usa getServerSideProps , la página no se genera estáticamente (SSG) y, en cambio, se procesa a pedido en cada solicitud al servidor (SSR).

Next.js también expondrá automáticamente un punto final de API que devuelve el resultado de llamar a getServerSideProps . Esto se está utilizando para el enrutamiento del lado del cliente.

Cuando el enrutamiento del lado del cliente a través de next/link o next/router , Next.js buscará este punto final de API expuesto para obtener los datos JSON que se convierten en los accesorios necesarios para representar la página del lado del cliente.

Este método es el más similar al actual getInitialProps , con la principal diferencia de que getServerSideProps siempre se ejecuta en el lado del servidor en lugar de en el navegador. Ya sea en la representación del lado del servidor o en la recuperación de la API cuando el enrutamiento del lado del cliente.

De manera similar a getStaticProps las propiedades se devuelven bajo una clave 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: {}
  };
}

El context contendrá:

  • params - Los parámetros en una ruta dinámica
  • req - El objeto de solicitud HTTP
  • res - El objeto de respuesta HTTP
  • query : la cadena de consulta (no estoy completamente seguro de esta, pero probablemente sea necesaria)

Escrito por @Timer , @ijjk , @lfades. Colaboró ​​con @rauchg , @jescalan y otros 🚀

Comentario más útil

¡La compatibilidad con la generación de sitios estáticos de próxima generación (SSG) se ha lanzado como estable en Next.js 9.3!

Esta versión también incluye soporte para "Modo de vista previa", o la capacidad de omitir la página renderizada previamente estáticamente y renderizar la página bajo demanda para usuarios autorizados .

Puede leer más sobre esto en nuestra publicación de blog . Si eres más práctico, ¡ve directamente a nuestros documentos !

Todos 250 comentarios

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

Estoy interesado en ver qué circunstancia necesitaríamos para devolver datos adicionales que no sean los que se pueden contener dentro de props . Encontré la explicación en línea "para controlar aún más el comportamiento por página" un poco vaga.

¡Parece muy interesante! ¿Sería el suyo un reemplazo de getInitialProps o al lado? Por ejemplo, para nuestro caso de uso, la API de obtención de datos es un servicio público. Entonces, en la navegación del lado del cliente, esperamos que el cliente llame directamente a la capa de API, mientras que en SSR el servidor lo llama. En el futuro, ¿este caso de uso continuaría resolviéndose con el método anterior?

Estoy interesado en ver qué circunstancias necesitaríamos para devolver datos adicionales que no sean los que se pueden contener dentro de props . Encontré la explicación en línea "para controlar aún más el comportamiento por página" un poco vaga.

Se trata más bien de probar el método en el futuro para que nos permita extenderlo más adelante si es necesario.

¡Parece muy interesante! ¿Sería el suyo un reemplazo de getInitialProps o al lado? Por ejemplo, para nuestro caso de uso, la API de obtención de datos es un servicio público. Entonces, en la navegación del lado del cliente, esperamos que el cliente llame directamente a la capa de API, mientras que en SSR el servidor lo llama. En el futuro, ¿este caso de uso continuaría resolviéndose con el método anterior?

En general, ese comportamiento tiene algunas desventajas, por ejemplo, la recuperación en cascada que podría ser lenta en ciertas áreas del mundo. El enfoque getServerProps permite almacenar en caché la respuesta de manera más eficiente.

¡Esto parece realmente interesante! ¡Buena idea!

Sin embargo, tengo preocupaciones sobre la implementación ...

Imaginemos que estoy alojando en Now.
Para la primera implementación, es obvio que todas las aplicaciones se basan en la implementación.

Luego, cambio algo de contenido en CMS y estoy buscando activar la reconstrucción de páginas SSG solamente, pero el código de la aplicación no ha cambiado.

Inmediatamente se dispara la alarma, que en este caso si activo la compilación, hay dos posibles soluciones:

1) No se reconstruye nada, ya que todo se almacena en caché, no se ha cambiado ningún código y blabla.
2) Lo --force , y ahora "todo" se reconstruye, pero solo requería que se reconstruyeran las páginas SSG.

_Estas son solo hipótesis, ya que eso depende de los sistemas de construcción en sí mismos: qué tan conscientes son de Next_

Esto probablemente afectaría a cualquier otra solución de alojamiento.

El siguiente tiene un .next/cache ... ¿cómo funcionaría esto con eso?

@joltmode ese es básicamente el caso de todos los generadores de sitios estáticos actualmente. .next/cache se conserva entre implementaciones en Now y se reutiliza. Tenga en cuenta que actualmente probablemente esté usando getInitialProps para este caso con almacenamiento en caché (potencialmente https://zeit.co/blog/serverless-pre-rendering), que se procesa dinámicamente en una función sin servidor y luego almacena en caché en nuestro CDN, esto el comportamiento sigue siendo totalmente correcto y seguirá funcionando si usa getServerProps .

Realmente asombroso, encajaría muy bien en cómo usamos Next para los proyectos de los clientes y eliminaría algunos códigos repetitivos que copiamos.

Una cosa a considerar es el nombre de getStaticProps y getServerProps, si devuelven un {props} y otras opciones potenciales en el futuro, ¿los * Props no serían confusos? ¿Quizás getStaticConfiguration, getStaticSetup, getStaticOptions serían más genéricos?

@kibs, los valores devueltos siempre se relacionarían con la forma en que se manejan los accesorios. Entonces el nombre está bien en mi opinión.

¡Esto es simplemente asombroso! Esto está resolviendo cada caso de uso y necesidad que he tenido recientemente o que podría pensar al desarrollar aplicaciones web tanto privadas como profesionales. Me acaba de impedir que inicie mi propio generador de sitios híbridos, ¡gracias!

También puedo relacionarme con que los nuevos métodos son mejores que los getInitialProps() y exportPathMap() , lo que me pareció un poco confuso al principio cuando comencé a usar Next.js y profundicé en SSR / SSG. El enfoque por página también tiene más sentido para mí.

¡No puedo esperar para probar esto!

Solo una nota al margen: en el último ejemplo, creo que a getServerProps() le falta un parámetro context .

Solo una nota al margen: en el último ejemplo, creo que a getServerProps () le falta un parámetro de contexto.

¡Reparado!

¡Esto suena genial! Me pregunto desde la perspectiva del usuario de TypeScript si tener getStaticProps , getStaticPaths y getServerProps como métodos estáticos en el componente de la página (como getInitialProps en este momento) ser más fácil de escribir / usar correctamente.

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, el problema con ese enfoque es que se vuelve significativamente más difícil sacudir los árboles (léase: casi imposible). Lo que significaría que se enviaría un código innecesario al navegador.

@timneutkens buen punto ... pero ¿no tendría aún más sentido un archivo separado? ¿O es algo como esto _de manera confiable_ que se puede sacudir el árbol?

// 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 podemos sacudir eso de manera confiable, pero también estamos discutiendo tener un archivo separado. Sin embargo, personalmente prefiero el enfoque de archivo único.

¡Parece muy interesante! ¿Sería el suyo un reemplazo de getInitialProps o al lado? Por ejemplo, para nuestro caso de uso, la API de obtención de datos es un servicio público. Entonces, en la navegación del lado del cliente, esperamos que el cliente llame directamente a la capa de API, mientras que en SSR el servidor lo llama. En el futuro, ¿este caso de uso continuaría resolviéndose con el método anterior?

En general, ese comportamiento tiene algunas desventajas, por ejemplo, la recuperación en cascada que podría ser lenta en ciertas áreas del mundo. El enfoque getServerProps permite almacenar en caché la respuesta de manera más eficiente.

Claro, pero estoy hablando de evitar el RTT en el servidor de reacción. Considere el caso en el que la salida SSR del servidor se almacena en caché en el proxy del servidor CDN / caché. Si a esto le sumamos la búsqueda de datos para la navegación del cliente que llaman directamente a una capa de API diferente (común a la web / aplicaciones / todos los clientes), significa que la capa del servidor Next.js no tiene que ampliarse tanto en un escenario de alto tráfico.

Entiendo su punto de búsqueda en cascada, pero darles a los consumidores la capacidad de tratar el servidor Next como una capa SSR frente a una fuente de datos permitiría configuraciones de escalado mucho mejores.

¡Parece muy interesante! ¿Sería el suyo un reemplazo de getInitialProps o al lado? Por ejemplo, para nuestro caso de uso, la API de obtención de datos es un servicio público. Entonces, en la navegación del lado del cliente, esperamos que el cliente llame directamente a la capa de API, mientras que en SSR el servidor lo llama. En el futuro, ¿este caso de uso continuaría resolviéndose con el método anterior?

En general, ese comportamiento tiene algunas desventajas, por ejemplo, la recuperación en cascada que podría ser lenta en ciertas áreas del mundo. El enfoque getServerProps permite almacenar en caché la respuesta de manera más eficiente.

Claro, pero estoy hablando de evitar el RTT en el servidor de reacción. Considere el caso en el que la salida SSR del servidor se almacena en caché en el proxy del servidor CDN / caché. Si a esto le sumamos la búsqueda de datos para la navegación del cliente que llaman directamente a una capa de API diferente (común a la web / aplicaciones / todos los clientes), significa que la capa del servidor Next.js no tiene que ampliarse tanto en un escenario de alto tráfico.

Entiendo su punto de búsqueda en cascada, pero darles a los consumidores la capacidad de tratar el servidor Next como una capa SSR frente a una fuente de datos permitiría configuraciones de escalado mucho mejores.

Creo que está malinterpretando que este nuevo comportamiento significa que realmente puede almacenar en caché los resultados completos en una CDN, dado que la CDN admite respuestas dinámicas. Anteriormente, esto no era posible de manera confiable con getInitialProps.

@timneutkens Jugué con canary, tratando de babel-plugin-preval código getStaticProps . Me encontré con un problema con fs .

Estoy tratando de leer los archivos .md de mi directorio ./pages/blog/ y recorrerlos para poder hacer una página de índice de blog con todas mis publicaciones.

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;

Este código conduce a este error:

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

IIRC de Razzle, este error tiene que ver con los stubs del sistema de archivos del paquete web (o la falta de ellos). Creo que una vez arreglé esto con Razzle agregando esto a la configuración del paquete web.

node: {
  fs: "empty";
}

Probé este next.config.js, pero solo hace que el error desaparezca. Sin embargo, parece que fs / fs-extra realidad no funciona, o lo hace y tal vez las rutas no (no me queda claro). ¿Alguna idea sobre eso?

Mi otra pregunta, de manera más general, es cuáles imaginas que serán las mejores prácticas para usar la importación frente a requerir en getStaticProps . Si no me equivoco, mi fragmento anterior intentará importar fs-extra en React isomorphically ??. Por tanto, ¿sería mejor cambiar la importación a un requisito en línea como este?

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

Creo que está malinterpretando que este nuevo comportamiento significa que realmente puede almacenar en caché los resultados completos en una CDN, dado que la CDN admite respuestas dinámicas. Anteriormente, esto no era posible de manera confiable con getInitialProps.

Ah, creo que entiendo lo que quieres decir. ¿Significaría eso que getServerProps en la primera generación de SSR crearía un punto final único, en un hash direccionable de contenido tal vez en la URL tal vez que luego podamos almacenar en caché en la CDN? El único inconveniente de esto sería que dicho caché no se podría compartir entre aplicaciones que no sean Next (android / ios) y aplicaciones Next. Además, con una fuente de datos externa, las directivas de control de caché están en sentido ascendente, pero aquí, dado que Next asumiría la responsabilidad de entregar los datos, necesitamos API o accesorios para especificar aquellos para los puntos finales de datos generados.

@jaredpalmer Supongo que https://github.com/zeit/next.js/issues/9524#issuecomment -558628066 (incluida mi inquietud acerca de la agitación confiable del árbol ) se resolvería teniendo un archivo separado que se compilaría completamente por separado de código de paquete de cliente? P.ej

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

or:

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

@jaredpalmer La agitación de árboles aún no se implementó en canary.

Como siempre, gracias por todo lo que hacen. Ha sido un placer trabajar con Next.js y, como dije antes, casi todas las versiones de funciones nos permiten _reducir_ el tamaño de las bases de código que administro. Es asombroso.

Es difícil ser crítico con este RFC ya que, tal como está escrito, es inmediatamente útil para MUCHAS aplicaciones. Sin embargo, quiero abordar una línea con la que no estoy seguro de estar de acuerdo:

" getStaticPaths reemplaza la necesidad de tener un exportPathMap y funciona por página".

En algunas aplicaciones, es impráctico o imposible conocer las rutas en el momento de la construcción. Algunos ejemplos serían:

  • Páginas de perfil de usuario
  • Páginas de productos (para empresas con un inventario que cambia rápidamente)
  • Páginas de detalles de órdenes de venta

Las rutas para páginas como esta probablemente tendrán la forma /entity-name/entity-id y las rutas dinámicas de Next funcionan realmente muy bien ya que puedes hacer cosas como router.push('/customers/[customerId]', '/customers/baer') . Todavía hay una trampa. Si planea entregar estos archivos de forma estática con algo como Serve, Netlify, NGINX, etc., deberá generar un conjunto de redireccionamientos para que los usuarios no obtengan un 404 al actualizar la página y, para hacerlo, aún necesita exportPathMap .

Lo siguiente se copia, casi como está, de una base de código en la que trabajo con regularidad:

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

Entiendo que este RFC no desaprueba ni elimina ninguna API y también reconozco que es posible crear estos redireccionamientos atravesando el directorio de compilación, por lo que incluso si estuviera en desuso, tengo una buena escotilla de ecape. Pero, no "elimina la necesidad de getStaticPaths ".

Nuevamente, gracias por su consideración en la forma en que ejecuta este proyecto.

¿Son getStaticProps / getStaticPaths y getServerProps mutuamente excluyentes? es decir, ¿sería posible tener una parte pre-renderizada y una parte dinámica al mismo tiempo?

Sí, son como uno es la generación estática y el otro es la representación del lado del servidor.

Esto corrige una de las grandes cosas que extraño de Gatsby antes de migrar a Next:

Tenemos un archivo JSON monolítico (cientos de kbs) del que extraemos datos para representar nuestras páginas que nunca cambia. En Gatsby, cargamos el archivo JSON en el esquema GraphQL y lo consultamos, solo obteniendo los datos que necesitábamos para representar una página determinada. Con Next, la forma más fácil / limpia que encontramos para hacer esto es import monolith from './monolith.json' , que requiere que el usuario descargue el archivo JSON completo.

Este RFC 100% aborda este caso de uso y acerca a Next un paso más a estar a la par con Gatsby en las áreas en las que Gatsby brilla (obviamente, Gatsby no puede hacer SSR en tiempo de ejecución, por lo que solo estoy hablando de renderizaciones estáticas en tiempo de construcción)

@timneutkens , ¡gracias por el RFC!

Tengo un caso de uso para Next.js que hablé recientemente con @rauchg.

Next.js ofrece DX muy fluido y algunos valores predeterminados razonables. Entonces, estoy interesado en usar Next.js para una aplicación renderizada solo del lado del cliente, una aplicación de Smart TV.

Las aplicaciones de Smart TV son aplicaciones web casi clásicas que se ejecutan mediante el motor del navegador de TV:

  1. La aplicación está empaquetada en un paquete: estilos, scripts, imágenes, _index.html_, certificados y archivo de configuración de TV.
  2. El paquete se envía para su revisión a la tienda de aplicaciones de la plataforma.
  3. Luego, el paquete se instala desde la tienda como una aplicación y lo ejecuta el usuario.

El caso es que el paquete está alojado estáticamente en el dispositivo de TV y no se carga desde el servidor. Por lo tanto, no es posible ninguna opción SSR (Node.js no está expuesto a los desarrolladores para estos fines). Pero la aplicación en sí es dinámica (digamos, Netflix).

Entonces, necesitamos ejecutar un SPA que esté alojado en un servidor web estático.

Según tengo entendido, la exclusión voluntaria de getServerProps (o getInitialProps ) ayudará a evitar SSR. Pero, ¿qué sucede con el renderizado dinámico en el cliente? ¿Y qué pasa con el enrutamiento en este caso? Según este RFC, el problema aún no se ha abordado. @timneutkens , ¿podría, por favor, sugerir la mejor manera de habilitar el renderizado solo del lado del cliente en Next.js? ¿Y si encaja con Next.js en primer lugar? ¡Gracias!

PD: Puedo crear un problema para este caso de uso si cree que es mejor discutirlo por separado.

@grushetsky puede crear un problema diferente. Esta es una pregunta completamente diferente a la que se está discutiendo en el RFC 👍

@timneutkens ¡ La promesa de este RFC es una de las cosas que me emocionó mucho con Next! Sin embargo, solo para aclarar, getInitialProps también existiría, ¿verdad?

Correcto @outdooricon - getInitialProps permanecerá en el futuro previsible.

Según el RFC:

Este RFC analiza exclusivamente las adiciones de API. Toda la nueva funcionalidad es completamente compatible con versiones anteriores y se puede adoptar gradualmente. Esta RFC no presenta desaprobaciones.

¡Excelente RFC, súper emocionado por esto!

He estado pensando en el getServerProps en relación con un caso de uso específico, poniendo los resultados en un caché. Dado que esto se convierte en un punto final de API y el resultado se entrega al componente como accesorios, ¿existe una forma prescrita de poner el resultado en una caché externa como Redux, GraphQL-caches, etc., del lado del cliente?

Si entiendo correctamente getInitialProps , ya que es estático y asincrónico, Next tiene la oportunidad de esperar a que se complete antes de renderizar el componente por primera vez. Esto nos permite poner cosas en un caché externo allí. Este no será el caso con getServerProps ya que se ejecuta en el servidor, y poner cosas en un caché en el ciclo de vida del componente parece significar que tenemos que tener un render donde los datos aún no están disponibles en el caché. , incluso si está disponible en accesorios?

Esto podría ser intencional, por supuesto, y podría estar perdiendo un enfoque, pero pensé en preguntar si es algo que se ha considerado.

Editar: Supongo que esto también se aplica a getStaticProps . 😄

Tal vez me lo haya perdido en alguna parte, pero ¿cómo manejamos situaciones en las que el contenido se almacena en caché, pero se actualiza en la base de datos o se crea una nueva publicación de blog? ¿Es necesario hacer una nueva construcción automáticamente? Supongo que sí.

¡En primer lugar! Gran propuesta, es una mejora masiva con respecto a exportPathMaps en el caso de uso de la mayoría de las personas. Es muy apreciado. Dicho esto, estoy luchando por entender cómo podríamos hacerlo funcionar con la internacionalización de rutas.

¿Hay alguna sugerencia sobre cómo manejar las rutas con prefijo i18n? Mi caso de uso específico requiere construir algunos miles en páginas con diferentes URL y prefijos de idioma de país.

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

Parece que getStaticPaths será realmente útil cuando el prefijo de la URL sea bien conocido, como en su ejemplo (usando /blog/[id].js ). Pero, ¿cómo crees que se verá una implementación getStaticPaths si necesita generar rutas a nivel raíz, con un prefijo dinámico (country-lang) y una ruta dinámica?

@reaktivo pages/[lang]/blog/[id].js -> en getStaticPaths proporciona todas las URL para renderizar estáticamente.

@timneutkens ¿ Alguna idea de cuándo estará disponible / comprobable?

En general, no proporcionamos ETA porque probamos ampliamente las funciones con las aplicaciones de producción para asegurarnos de que la solución sea la correcta.

Estas mejoras me harán desaprobar totalmente mi proyecto fenómico "no tan mantenido" (react ssg que nadie usa excepto yo). ¡Impresionante ver a Next.js agregando estas partes faltantes!

Quisiera aclarar una duda. Considerando el uso de un CMS como wordpress. Según tengo entendido, con el método getStaticPaths buscaría todas las publicaciones y pasaría una lista como:

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

El slug de cada publicación se usaría en el método getStaticProps para recuperar el contenido.
Esto sucedería en npm build.
Mi pregunta es sobre las nuevas publicaciones que se agregarán después de la compilación.
¿Se usaría el método getStaticProps para buscar esta nueva publicación por slug?
¿Esta nueva publicación tendrá un archivo .html como el de la compilación anterior?
Me encanta trabajar con next y en varios proyectos que tengo esto sería muy bueno.

Nada relacionado directamente, pero el soporte no puede darme una respuesta que coincida con mi pregunta.

Lo que sugieres aquí podría ser la solución, pero mientras tanto, no puedo hacer nextJS para construir un JAMSTACK basado en cambios de webhooks.

si tuviera getInitialProps, seré renderizado por el servidor.
Si no lo hago, solo estoy CDNizado, pero sin prerrepresentación, ¿no lo es? Y la página no tendrá contenido siempre que XHR no haya regresado (adiós SEO)

¿Tiene algún ejemplo en ejecución con ahora de Jamstack con nextJS y podríamos hacerlo en netlify?

Gracias,
Andréas

Hola @ScreamZ : este cambio es, creo, lo que permite construir un sitio completamente estático con nextjs. Hemos podido compilar un sitio nextjs en estático usando next export durante mucho tiempo, pero aún obtendría datos en las transiciones de ruta del lado del cliente usando getInitialProps . Con la capacidad de usar getStaticProps , puede ejecutar transiciones del lado del cliente sin que se obtengan datos adicionales: todos los datos obtenidos en getStaticProps se obtienen una vez, en el momento de la compilación, y no se actualizan en su sitio en vivo a menos que lo reconstruya nuevamente. Esta es la arquitectura clásica de los sitios estáticos basados ​​en datos, vincula tu fuente de datos a tu host a través de un webhook y cuando la fuente de datos cambia, le dices al host que reconstruya tu sitio.

Hay muchos ejemplos existentes de sitios web nextjs completamente estáticos, y es trivial ejecutar un sitio nextjs en netlify. El sitio web de mi empresa se ejecuta actualmente en nextjs y está alojado en netlify, con suerte esto sirve como un buen ejemplo.

Vale la pena señalar que el servicio de alojamiento de zeit también es algo que vale la pena considerar seriamente. El precio es bastante similar, y su integración con los sitios de nextjs es insuperable: literalmente, ni siquiera necesita configurar nada en absoluto, simplemente vincula github y el alojamiento de zeit reconocerá que está ejecutando nextjs y lo configurará e implementará automáticamente. todo.

Esto no es un anuncio de ninguna manera, no trabajo para zeit, solo un respaldo genuino. Absolutamente puede hacer que funcione con netlify, y personalmente lo he hecho para varios sitios como prueba. Pero deberá comprender a fondo cómo funciona nextjs, y deberá asegurarse de que todo esté configurado correctamente para que funcione sin problemas en netlify. Si está buscando el alojamiento más simple e infalible para un sitio nextjs, le daría una oportunidad al alojamiento de zeit.

@jescalan Gracias por este gran intercambio 🙏🏻

No tengo ningún problema al usar NextJS con netlify, porque puede usar Publish directory para especificar la carpeta out . Pero en zeit Now, no hay forma de decir, por favor, no use SSR pero use estático con next export .

@ScreamZ esto es cierto, pero depende de cómo se defina exactamente un sitio "completamente estático". Si usa getStaticProps para todas sus páginas con el servicio de alojamiento de zeit, lo que obtendrá es efectivamente igual a un sitio estático, incluso si no ejecuta next export , ya que todas las páginas con getStaticProps se compilan solo cuando se implementa el sitio y, después de eso, se sirven directamente desde la CDN.

La principal diferencia es que, hasta donde yo sé, no hay una manera de forzar que todas las páginas sean estáticas en el alojamiento de zeit (editar: zeit lo cambió recientemente para que cualquier sitio con una configuración que contenga exportPathMap se ejecute un sitio completamente estático, por lo que esto ya no es cierto). Las páginas con getStaticProps comportan exactamente igual que las páginas generadas por next export : una única copia estática de la página se sirve directamente desde la CDN en cada visita. Pero también podría ejecutar algunas páginas con getServerProps o getInitialProps y se comportarían como páginas renderizadas por el servidor. Personalmente, veo esto como un beneficio: si se necesita una ruta SSR, simplemente puede usar un método de obtención de datos diferente y esa ruta única ahora es SSR, mientras que todas las demás rutas pueden permanecer estáticas.

@jescalan Gracias,

Así que solo necesito esperar a que esto se implemente, mientras tanto, usaré netlify para estática

¿Hay alguna historia sobre la configuración de SSG? Específicamente, nos gustaría usar artefactos de compilación compartidos pero ejecutar next export con diferentes configuraciones para QA / prod. Estos valores de configuración solo se leerían en getStaticProps . ¿Usaría esto serverRuntimeConfig o publicRuntimeConfig o process.env directamente?

@ScreamZ @jescalan He conseguido cero-config next export soporte en Now hoy junto con @Timer (se merece todos los créditos). Tu puedes hacer:

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

Y funcionará automáticamente.

Déjame saber cómo te va 🙏

Sí, yo fui el tipo que pidió soporte y me dijeron que esto se ha implementado todavía 😅 Por lo que puedo ver, ¿necesitarás definir un mapa de exportación en la configuración?

@ScreamZ no, solo puedes agregar next build && next export como se muestra arriba y funcionará.

@timneutkens Si reemplazo getInitialProps con getServerProps , ¿todavía necesito agregar target: 'serverless' al archivo de configuración para habilitar Server Pre Rendering ? Gracias.

¿Cómo podemos probar estos?

¿Cómo podemos probar estos?

Supongo que todos estos métodos actualmente necesitan el prefijo unstable_ para ser reconocidos.

por ejemplo, unstable_getStaticProps

@timneutkens

@ScreamZ @jescalan He conseguido cero-config next export soporte en Now hoy junto con @Timer (se merece todos los créditos). Tu puedes hacer:

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

Y funcionará automáticamente.

Déjame saber cómo te va 🙏

Mi script de compilación está haciendo un poco más de cosas, pero parece que funciona a las mil maravillas:

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

Además, ¡es genial! Era exactamente lo que estaba buscando 😅 (¡Adiós GatsbyJS, mi marco favorito ahora es tan fuerte como tú!)

Muchas gracias por tanta reactividad.

También actualicé a 9.1.6 y vi sorprendentemente que
Screenshot 2019-12-21 at 19 25 43

Pensé que ese hilo era un RFC, parece que ya está abierto para nosotros ahah, ¿no?
Sin embargo, los tipos de TypeScript no están habilitados en 9.1.6.

¡Maldita sea, estoy tan emocionado por eso ahora! 🤣

Ultimas preguntas:

  • Si lo consigo, getInitialProps quedará obsoleto en el futuro? ¿O sigue siendo relevante en algunos casos? ¿Un ejemplo?
  • next export también se puede desaprobar en favor de páginas con getStaticProps y next build solamente?

Gracias por esa gran herramienta 🙏🏻

Si lo consigo, getInitialProps quedará obsoleto en el futuro. ¿O sigue siendo relevante en algunos casos? ¿Un ejemplo?

Como se dijo en el RFC inicial:

Este RFC analiza exclusivamente las adiciones de API. Toda la nueva funcionalidad es completamente compatible con versiones anteriores y se puede adoptar gradualmente. Esta RFC no presenta desaprobaciones.

Pensé que ese hilo era un RFC, parece que ya está abierto para nosotros ahah, ¿no?

No lo es, lo estamos probando en aplicaciones ZEIT y parte de la visibilidad que aparece ya ha aterrizado (por ejemplo, el árbol de páginas que vio).

¿La próxima exportación también puede quedar obsoleta en favor de las páginas con getStaticProps y solo la próxima compilación?

Correcto, en general terminará sin usar next export . Se mantendrá por razones de compatibilidad con versiones anteriores, pero en general querrá crear una aplicación híbrida, ya que le brinda todos los beneficios de la exportación con soporte para otras funciones como rutas API y optar por la representación del lado del servidor para algunas páginas.

¿Cómo podemos probar estos?

Supongo que todos estos métodos actualmente necesitan el prefijo unstable_ para ser reconocidos.

por ejemplo, unstable_getStaticProps

Recomiendo encarecidamente no usarlo todavía, es experimental y puede romperse entre lanzamientos.

Así que he estado jugando con esta función y he observado que el archivo JSON que contiene los datos de la página siempre se recupera después de acceder a la página SSG desde otra página.

¿Tienen planes de realizar alguna optimización de precarga para el archivo JSON?
Quizás precargarlo cuando el usuario está a punto de navegar a la página (es decir, el usuario está colocando el cursor sobre un enlace SSG) o precargarlo como si estuviera precargando otras páginas js a las que se hace referencia desde un componente de enlace.

¡Me encanta esa característica, por cierto!

¿Tienen planes de realizar alguna optimización de precarga para el archivo JSON?

si.

Por lo que vale, estoy a favor de las exportaciones de estas funciones que se pueden agitar en el árbol en lugar de archivos separados.

¿Cuál es el estado de esta función? ¿Cuáles son sus bloqueadores?

@mikestop continúa este RFC actualmente está siendo probado internamente por nuestro equipo y algunos socios selectos. Puede optar por su comportamiento altamente experimental utilizando los prefijos unstable_ , como se mencionó anteriormente . 😄

Sin embargo, no migre las cargas de trabajo de producción a los nuevos métodos, ya que aún podemos actualizar las API de manera importante.

Personalmente, lo uso para la generación de sitios estáticos de 8 a 20K páginas (con la posibilidad de tener algunas solicitudes dinámicas en algunas páginas). Funciona muy bien (excepto por el límite de archivos de 10K en Now), lo único que me da vergüenza es que sin el método getStaticPaths, se llama a getStaticProps en cada recarga. Un comportamiento que podría ser bueno es que la primera llamada crea el archivo json y la siguiente lo usa.

¿Están planificadas las construcciones incrementales? Entonces, ¿solo se reconstruye el contenido nuevo / modificado?

Puede optar por su comportamiento altamente experimental utilizando los prefijos unstable_ , como se mencionó anteriormente .

Me gustaría probar el método unstable_getServerProps , pero parece que está ignorado en este momento y no puedo encontrarlo en ninguna parte del repositorio zeit/next.js . ¿No se ha implementado todavía o simplemente lo estoy haciendo mal?

¿Están planificadas las construcciones incrementales? Entonces, ¿solo se reconstruye el contenido nuevo / modificado?

La implementación se diseñó teniendo en cuenta las reconstrucciones incrementales, pero aún no se admite (ni se trata en este RFC).

Tenga la seguridad de que la arquitectura está lista y exploraremos esto después de que estas características se estabilicen.
¡Es por eso que getStaticProps se define por página, y no una vez para toda la aplicación!

Me gustaría probar el método unstable_getServerProps, pero parece que está ignorado en este momento [...]

getServerProps no está disponible en vista previa, ¡lo siento!

getServerProps no está disponible en vista previa, ¡lo siento!

Gracias por el aviso. Definitivamente estaré viendo este hilo, porque cuando llegue, tendré un _bunch_ de código que se puede reemplazar cambiando el nombre de una sola función. 😍

Aclare, no estoy 100% seguro de si getServerProps / getStaticProps están disponibles para usar o no.

Basado en este hilo: No

Pero si ese es el caso, entonces me pregunto por qué mi terminal lo mencionó cuando ejecuté next build si aún no están disponibles. Ver el mensaje me dejó con la suposición de trabajo inicial de que estos métodos estaban en producción, y me tomó un tiempo descubrir que no lo estaban. Solo tengo curiosidad sobre el razonamiento o si hay algo que estoy malinterpretando.

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

(en la próxima versión 9.1.6)

Gracias

@stevenjchang están disponibles usando la siguiente sintaxis en pages/**/*.js :

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

Y también debo agregar, son maravillosos, aunque todavía son un poco toscos cuando se usa el servidor de desarrollo.

aunque todavía son un poco toscos cuando se usa el servidor de desarrollo.
@mikestopcontinúa

¿Podría dar más detalles sobre esto? Nadie más nos ha dado comentarios negativos sobre la experiencia del servidor de desarrollo, ¡y nos encantaría resolverlo!

@Timer Me gusta mucho la nueva API. Mi principal problema durante el desarrollo es que el json se vuelve a solicitar en cada carga. Esto ralentiza las pruebas, pero también tergiversa la experiencia del usuario cuando navega por el sitio.

Por "en cada carga", ¿te refieres a la carga de la página? ¿O reconstruir? O...?

@mmmeff Cada vez que navega a la misma ruta, vuelve a solicitar el archivo json. Entonces, si hace clic de un lado a otro entre dos páginas, pasa mucho tiempo esperando los datos.

@mikestop continúa: este es el comportamiento previsto, ya que los datos más actualizados suelen ser preferibles en el desarrollo. ¡Estaría dispuesto a discutir algunas mejores heurísticas en un nuevo número!

@timneutkens Este RFC parece muy prometedor. Tengo algunas preguntas / inquietudes sobre la seguridad y cómo funciona exactamente.

Tomemos un caso comercial genérico que se basa tanto en SSR como en SSG.

Contexto

Queremos mostrar cierta información en un sitio web (también conocido como "aplicación").
Esa información se almacena en un BDD al que se puede acceder a través de una API GraphQL.
Parte de esa información es pública, otra privada (es decir, correos electrónicos de usuario / contraseña).

La aplicación utiliza dos etapas:

  • Una etapa de "preparación", donde el cliente puede ver cambios en tiempo real en la aplicación de preparación (actualiza esa información a través de algún back-office o similar)
  • Una etapa de "producción", donde el cliente no tiene acceso y no puede actualizar nada por sí mismo. Para actualizar la aplicación de producción, se debe realizar una nueva implementación. (piden que se haga un nuevo despliegue de producción, desde su back-office)

En este escenario, usamos SSR y SSG:

  • La aplicación de ensayo usa SSR, porque recupera en tiempo real los datos de la API GraphQL (al crear una página)
  • La aplicación de producción usa SSG, porque cuando se realiza una nueva implementación, obtiene los datos de la API GraphQL y genera páginas estáticas a partir de ella (por lo tanto, son estáticas y ya no cambiarán, no se realizarán consultas a la API GraphQL en tiempo de ejecución (al menos no al cargar una página))

Este escenario debería ser lo suficientemente genérico y debería ser (en mi humilde opinión) uno de los principales casos de uso del uso de SSG.
La aplicación de producción no es más que una instantánea de la aplicación de ensayo.

Unas cuantas preguntas:

  1. ¿Es esto posible con este RFC ? Hacer que la misma aplicación se comporte de manera diferente en función de una "etapa" determinada (producción / puesta en escena)
  2. ¿Cómo se inyectan los datos extraídos de la API GraphQL?

    • En la preparación, se obtienen dinámicamente a través de SSR o CSR a medida que el usuario navega por las páginas (y estarán disponibles en el navegador si se obtienen durante la CSR)

    • En producción, se obtienen en el momento de la compilación, pero luego, ¿se almacenan dentro de una variable global JS y, por lo tanto, cualquier persona puede leerlos? (preocupación por la seguridad, ya que debemos ser conscientes de no obtener datos confidenciales que puedan estar disponibles en el navegador, de manera similar a como se hace cuando se usa CSR)

  3. ¿Le preocupa este enfoque con SSR / SSG mixtos? (seguridad, prestaciones, mantenibilidad, etc.)

¿Cuándo planeas lanzar esto? ¿Será una actualización importante (v10) o una actualización compatible con versiones anteriores?

Oye,

¿Alguien ha probado esta solución con un servidor personalizado y ha hecho que funcione?

Ejemplo:

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

¿Por qué getStaticProps incluir la cadena de consulta? Actualmente tengo una página que tengo que SSR simplemente para obtener los parámetros de consulta sin volver a renderizar. El uso del gancho useRouter provoca múltiples re-renderizaciones, ya que la consulta es inicialmente un objeto vacío. Esta es una página que se utiliza para el seguimiento de conversiones, por lo que, obviamente, no es para empezar.

@pjaws El RFC menciona específicamente que getStaticProps es para generación estática. El HTML estático no puede recibir una cadena de consulta.

Entonces, ¿por qué puede recibir parámetros de URL dinámicos? ¿Cómo es eso diferente?

El martes 14 de enero de 2020 a la 1:30 a. M. Tim Neutkens [email protected]
escribió:

@pjaws https://github.com/pjaws El RFC que menciona específicamente
getStaticProps es para generación estática. HTML estático no puede recibir un
querystring.

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/zeit/next .
o darse de baja
https://github.com/notifications/unsubscribe-auth/AMVRRIRJXLYC4MC4U7DH7NDQ5WA2NANCNFSM4JRPBELQ
.

Porque en getStaticPaths tienes que devolver las páginas que se renderizarán en el momento de la compilación.

Estos cambios parecen muy prometedores, ¡un gran trabajo como siempre! 👍

Me pregunto sobre el caso de uso de tener getInitialProps en _app.js para satisfacer las necesidades de datos compartidas en las páginas (por ejemplo, configurar proveedores de contexto). ¿Entiendo correctamente que es imposible usar getStaticProps de la misma manera? ¿Solo es posible definirlo en páginas individuales?

Me pregunto sobre el caso de uso de tener getInitialProps en _app.js para satisfacer las necesidades de datos compartidas en las páginas (por ejemplo, configurar proveedores de contexto). ¿Entiendo correctamente que es imposible usar getStaticProps de la misma manera? ¿Solo es posible definirlo en páginas individuales?

Correcto, inicialmente solo será para páginas individuales. Podría reconsiderarlo más adelante. El getInitialProps de _app aún se llamará al exportar a HTML estático para que pueda moverse gradualmente a getStaticProps.

hola chicos, una pregunta relacionada: ¿cómo se tratarán los activos? porque estoy viendo ahora que si uso un CMS sin cabeza (incluso wordpress o graphcms o lo que sea), la URL del activo se usa en el html estático.

Aquí hay dos preferencias: que los enlaces de activos se utilicen como tales.
Pero lo más probable es que descargue el activo, cree el html (enlace a él localmente) y luego coloque un CDN al frente. Ésta es la práctica mucho más aceptable.

Esto también se relaciona muy bien con el uso de sistemas de implementación como Netlify, que tienen una infraestructura disponible globalmente mucho más adecuada que algo como DatoCMS o Graphcms. Entonces, si estoy usando Netlify como implementación, me gustaría que todo se sirviera desde el dominio de Netlify y dejar que funcione su magia.

@sandys Si entiendo correctamente en https://github.com/zeit/next.js/issues/9054#issuecomment -570427085, se supone que debe descargar los activos, almacenarlos en .next/static y crear un enlace usted mismo en getStaticProps .

También existe la idea de tener rutas de API estáticas, pero no estoy seguro de cómo controlaría exactamente el comportamiento de almacenamiento en caché del navegador con eso.

@Janpot gracias por vincularlo. Los comentarios allí parecen indicar que estas cosas tienen que ser hechas por ti mismo.

Agregue mi solicitud para tener esto integrado. Quizás el # 9054 sea más genérico, pero estoy pensando desde la perspectiva de SSG y esto es EXTREMADAMENTE esencial.

Olvidé mencionarlo, pero el hash de activos también será esencial para SSG.

@homoky , no has podido hacer que eso funcione, ¿hiciste algún progreso mientras tanto?

@homoky , no has podido hacer que eso funcione, ¿hiciste algún progreso mientras tanto?

No es posible y tampoco está planeado: # 10071

😢

@sandys en realidad, la solución es mucho más simple cuando usa https://github.com/zeit/next.js/issues/9081 para agregar una reescritura de, por ejemplo, /images al CMS. Por ejemplo, en ZEIT Ahora ya almacenaría en caché el resultado cuando se agregan los encabezados correctos, sin necesidad de descargas adicionales (sobrecarga masiva en la compilación).

@timneutkens gracias por responder.
No estoy del todo seguro de lo que quieres decir. Así que usamos netlify, ¿estás sugiriendo que mantengamos las URL de CMS como tales y al frente de una capa de CDN sobre ellas?
No estoy muy seguro de si netlify (cloudfront que estamos planeando usar) puede funcionar sin problemas con todos estos servicios.

Si las imágenes se descargan y forman parte de la implementación, todo este problema se simplifica enormemente. Porque configuro CDN para almacenar en caché desde la URL base (que en mi caso se servirá desde s3).

No estoy del todo seguro si su solución se basa en que yo use Zeit NOW

Si las imágenes se descargan y forman parte de la implementación, todo este problema se simplifica enormemente. Porque configuro CDN para almacenar en caché desde la URL base (que en mi caso se servirá desde s3).

En realidad, esto hace que el proceso de construcción sea mucho más complejo y 10 veces más lento, definitivamente no más simple.

No estoy del todo seguro si su solución se basa en que yo use Zeit NOW

Funciona con todos los servidores proxy del mundo. Incluido Cloudfront.

@timneutkens somos

Ciertamente no estoy defendiendo que active esto para todos. Mucha gente estará feliz de hacer deeplinking a un CMS. Pero tenemos un sitio de alto tráfico y esto es definitivamente algo que los sitios como nosotros necesitan.

Además, perdóname, pero no entendí tu solución. ¿cómo deberíamos configurar esto? No tengo control sobre qué URL utiliza un CMS. Por ejemplo, Datocms comienza a servir desde www.datocms-assets.com/ . ¿Cómo usamos la solución en # 9081?

en realidad somos independientes del tiempo del proceso de construcción. no importa si lleva más tiempo

Esto puede ser cierto para su aplicación, pero no es el caso para la mayoría de las aplicaciones.

pero por muchas razones (incluidos todos los recursos que se publican desde una URL base conocida), sería muy preferible tener esto integrado en la compilación.

Realmente no tiene que ser como se dijo, puede usar una reescritura que envíe /images/* a la url cms, por ejemplo www.datocms-asset.com/* o similar. Y luego simplemente vincule todas las imágenes usando /images .

Tenga en cuenta que esto está empezando a salirse del tema.

@sandys en realidad, la solución es mucho más simple cuando usa # 9081 para agregar una reescritura de eg / images al CMS. Por ejemplo, en ZEIT Ahora ya almacenaría en caché el resultado cuando se agregan los encabezados correctos, sin necesidad de descargas adicionales (sobrecarga masiva en la compilación).

@timneutkens Solo para

  1. optimizando las imágenes
  2. hash de las imágenes y sirviéndolas bajo este hash
  3. proporcionar un mapa de la URL de la imagen a la URL de la imagen hash que se puede descargar en getStaticProps para reasignar las URL de la imagen a su contraparte inmutable en el CMS

Lo cual, supongo, no es imposible. Solo quiero asegurarme de que esta sea la configuración propuesta.

Los proveedores de

@sandys, esto no está relacionado con SSG RFC, así que siéntase libre de crear un nuevo problema cuando se publique.

sin embargo, solo quería mencionar que en todas nuestras mentes, esto está estrechamente relacionado con SSG. Dado que el caso ideal es que el comando de exportación SSG haga esto. En general, esto no es necesario en otros casos.
El mejor de los casos es que esta sea una característica opcional durante la próxima exportación.

Pero, como desee, respete su decisión.

Pero es algo que next export ni siquiera hace actualmente. De ahí por qué es algo completamente nuevo y no relacionado con este RFC.

Tampoco lo haría con getServerProps y renderizado bajo demanda.

Los proveedores de

👍 sí, eso tiene sentido. Pero eso también significa que si usa imágenes en su proyecto y las quiere optimizadas y almacenadas en caché, tiene 2 opciones:

  1. crear una configuración de paquete web personalizado
  2. utilizar un CMS externo

editar:

Y si lo entiendo correctamente, file-loader ya está incluido para CSS. ¿No es una cuestión de habilitarlo también para JS?

@Janpot, el punto específico que mencionó Sandeep es que las URL vendrían de una fuente externa, no del proyecto en sí. Incluir el cargador de archivos de forma predeterminada es una solicitud de función diferente.

Me di cuenta de que para los sitios implementados en ZEIT Now, cuando tengo una página con una URL dinámica que usa las nuevas API estáticas, para las páginas que no se han generado estáticamente usando unstable_getStaticPaths , la función unstable_getStaticProps ejecuta en el servidor en tiempo de ejecución, en lugar de devolver un 404.

Por ejemplo, tengo una página /blog/[slug].js , cuyo getStaticPaths devuelve la matriz:

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

y mi getStaticProps tiene cierta lógica para leer un archivo basado en el slug. Cuando visito /blog/hello la página se renderiza previamente como se esperaba, pero cuando visito una página no válida como /blog/doesnt-exist , getStaticProps ejecuta en tiempo de ejecución y obtengo un error 500, en lugar de un 404. O si agrego manejo de errores, entonces la página se procesa, en lugar de un 404, a pesar de no estar listada en la salida de getStaticPaths .

¿Es esta lógica intencional?

Esto es una gran mejora. Estábamos a punto de escribir algunos scripts preconstruidos para hacer precisamente esto.
Acabo de probar mover uno de nuestros sitios a unstable_getStaticPaths y unstable_getStaticProps en Next 9.2, y funcionó bien.

Tenemos una regresión en comparación con exportPathMap : al construir una ruta usando exportPathMap , puede especificar algo como esto:

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

y la construcción estática se construirá

/path
   /to
     /page
       index.html

Cuando devuelve el equivalente de unstable_getStaticPaths en la plantilla [slug].jsx ,

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

Siguiente 9.2 genera '% 2Fpath% 2Fto% 2Fpage` en lugar de los directorios anidados.

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

La construcción de directorios (que coincida con el comportamiento existente de exportPathMap) es importante para la forma en que estamos construyendo páginas. Usamos un solo archivo de plantilla, pero la ruta publicada puede estar anidada arbitrariamente.

@dpfavand en ese caso, querrá utilizar una ruta general: https://nextjs.org/blog/next-9-2#catch -all-dynamic-routes

Potencialmente, podemos advertirle cuando intente devolver una ruta que incluya barras, pero el comportamiento es correcto cuando usa [slug].js , en su caso, desea [...slug].js .

¿Cuándo se espera que aterrice? ¿Estará en un parche de 9.2 o en su propia versión menor?

Realmente apreciamos todo el entusiasmo en torno a esta función. Como se mencionó en otra parte, generalmente no compartimos los cronogramas de las funciones, ya que queremos asegurarnos de que tengan la experiencia de desarrollador adecuada, las limitaciones y la prueba de futuro.

Como es una característica nueva, será menor.

Sí, lo entendería normalmente, pero el blog 9.1.7 dio la impresión
ya estaba en libertad.

El viernes 17 de enero de 2020 a las 5:05 p.m. Tim Neutkens [email protected]
escribió:

Realmente apreciamos todo el entusiasmo en torno a esta función. Como se mencionó
en otros lugares, por lo general, no compartimos las líneas de tiempo de las funciones como queremos
asegurarse de que tengan la experiencia de desarrollador adecuada, las limitaciones y el futuro
prueba.

-
Estás recibiendo esto porque hiciste un comentario.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/zeit/next .
o darse de baja
https://github.com/notifications/unsubscribe-auth/ADKINGBVCG6MFMOG5U2FGMDQ6ITRXANCNFSM4JRPBELQ
.

>

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

¿Hay algo como getStaticProps pero que se ejecute solo una vez para toda la aplicación en lugar de por página?

Mi caso de uso es que tengo un Contexto de reacción ( PricingPlansContext ) que utilizan varias páginas y quiero que los datos (planes de precios) se recuperen de mi servidor externo solo una vez, en el momento de la compilación ( next export ). Nunca en tiempo de ejecución y sin tener que agregar getStaticProps de cada página.

EDITAR: Encontré un comentario relacionado arriba: https://github.com/zeit/next.js/issues/9524#issuecomment -574179540. Ojalá se considere.

Utilizo babel plugin-preval` para eso, aunque también he visto a personas escribir un
json dentro de exportPathMa () con next.config.js, que luego importan
dentro de su código.

Terminé escribiendo un archivo json usando un script npm por ahora, pero gracias por sugerir exportPathMap, tal vez sea un lugar mejor.

@dpfavand en ese caso, querrá utilizar una ruta general: https://nextjs.org/blog/next-9-2#catch -all-dynamic-routes

Potencialmente, podemos advertirle cuando intente devolver una ruta que incluya barras, pero el comportamiento es correcto cuando usa [slug].js , en su caso, desea [...slug].js .

@timneutkens gracias por el seguimiento. Probé dos métodos sin éxito. Básicamente, cuando se especifica el valor de slug como una cadena en getStaticPaths , no se pasa a getStaticProps en absoluto. Al devolver el valor de slug como una matriz, la compilación falla ya que el valor debe ser una cadena.

Caso 1, asumiendo un archivo pages/[...slug].jsx , slug como cadena:

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

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

En el caso anterior, params en getStaticProps es un objeto vacío, sin clave slug .

Caso 2, pages/[...slug].jsx , slug como matriz,

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

En el caso 2, la compilación falla con

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

Solo veo parámetros de ruta en los ejemplos getStaticPaths anteriores. ¿Será posible SSG rutas que incluyan parámetros de consulta? Por ejemplo:

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

Estoy pensando especialmente desde la perspectiva de un sitio de comercio electrónico, donde sería difícil cubrir todas las facetas de la búsqueda de productos en el pathname de una URL.

Publiqué un mensaje aquí recientemente y no he recibido respuesta; esencialmente, getStaticProps se comporta como getServerProps cuando un sitio se implementa en ZEIT Now (es decir, ignorando getStaticPaths y gestionando solicitudes dinámicamente) - ¿Creo que esto es un error?

@dpfavand ¡ yo también estoy experimentando exactamente lo mismo! Intentando construir un sitio de inicio para agilitycms y nextjs con enrutamiento dinámico de páginas basado en páginas en el CMS.

@timneutkens gracias por el seguimiento. Probé dos métodos sin éxito. Básicamente, cuando se especifica el valor de slug como una cadena en getStaticPaths , no se pasa a getStaticProps en absoluto.

Caso 1, asumiendo un archivo pages/[...slug].jsx , slug como cadena:

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

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

En el caso anterior, params en getStaticProps es un objeto vacío, sin clave slug .

Por cierto, ¡mundo pequeño! Gracias de nuevo por hablar en fastr_conf.

Hola @timneutkens ,

Estoy muy emocionado con la idea de hacer que next.js se comporte como un generador de sitios estáticos.

Me gustaría preguntar cómo se pueden usar los métodos getStaticProps y getStaticPaths en caso de que se solicite una gran cantidad de datos una vez y luego se use para generar diferentes páginas.

Por ejemplo, estoy usando un cliente SDK de JavaScript de un CMS basado en API que tiene un método para buscar todos los objetos disponibles. Algunos de estos objetos representan páginas del sitio.

const entries = await cmsSdkCient.getEntries();

Hasta ahora, he estado usando el método exportPathMap para recuperar todas las entradas de CMS a la vez y generar un mapa entre las rutas de estas páginas y sus datos. La función exportPathMap hace dos cosas:

  1. Proporciona un mapa de páginas con sus datos y ssr: true consumidos por getInitialProps en el momento de la exportación
  2. Escribe los mismos datos, esta vez con ssr: false , en archivos init-props.json , ubicados en la carpeta que coincide con la ruta de cada página. Luego, cuando se llama a getInitialProps desde el cliente, los datos necesarios se cargan desde init-props.json de la página correspondiente.


next.config.js usando 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 / my_page.js usando 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();
    });
  }
};

Puedo ver la gran ventaja de usar los métodos getStaticProps y getStaticPaths que reducirán gran parte de mi código relacionado con guardar archivos JSON y cargarlos desde el cliente.

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

Lo que me preocupa es la pregunta: ¿cómo puedo optimizar el flujo de trabajo para traer todas las entradas una vez, en lugar de buscarlas cada vez que se llaman getStaticProps o getStaticPaths ?

Otra pregunta, podría no estar necesariamente relacionada con este tema, pero como estamos en el mundo de los SSG y las fuentes de datos remotas, vale la pena preguntar. Suponiendo que next.js se ejecute en modo de desarrollo, ¿cómo se puede notificar a next.js para que vuelva a ejecutar estos métodos para recuperar los datos remotos y reconstruir el sitio?

@smnh Dado que es "solo JavaScript", puede recuperar sus entradas una vez y almacenar en caché los resultados en su método de obtención de datos. Cuando se invoca nuevamente en los métodos getStatic * de alguna otra página, la red no será atacada nuevamente.

En cuanto a su segunda pregunta, lo hace automáticamente. Ejecute next dev y estará listo.

Solo veo parámetros de ruta en los ejemplos getStaticPaths anteriores. ¿Será posible SSG rutas que incluyan parámetros de consulta? Por ejemplo:

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

Estoy pensando especialmente desde la perspectiva de un sitio de comercio electrónico, donde sería difícil cubrir todas las facetas de la búsqueda de productos en el pathname de una URL.

No creo que esto tenga sentido en el contexto de ssg. SSG genera un archivo para cada entrada: los parámetros de consulta no forman parte del nombre del archivo, por lo que necesitaría una capa de servidor para reescribir las solicitudes en un archivo real. (¿Cuál sería el nombre de su archivo estático en el ejemplo anterior?) Sugeriría considerar preprocesar la vista predeterminada (lo que obtiene si visita la página sin facetas) y actualizar en el lado del cliente si hay parámetros de consulta en la solicitud. Pero eso se convierte en un problema más allá de este SSG RFC.

@dpfavand ¡ yo también estoy experimentando exactamente lo mismo! Intentando construir un sitio de inicio para agilitycms y nextjs con enrutamiento dinámico de páginas basado en páginas en el CMS.

@timneutkens gracias por el seguimiento. Probé dos métodos sin éxito. Básicamente, cuando se especifica el valor de slug como una cadena en getStaticPaths , no se pasa a getStaticProps en absoluto.
Caso 1, asumiendo un archivo pages/[...slug].jsx , slug como cadena:

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

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

En el caso anterior, params en getStaticProps es un objeto vacío, sin clave slug .

Por cierto, ¡mundo pequeño! Gracias de nuevo por hablar en fastr_conf.

¡Oye! El equipo de Nextjs comenzó a abordar esto, hay un ticket abierto para abordar algunos problemas adicionales con la implementación actual de Canary: https://github.com/zeit/next.js/issues/10190

@smnh, lo que termino haciendo es tener un script que

Para las reconstrucciones, tengo webhooks configurados en el CMS para activar los enlaces de compilación de Netlify cuando cambia el contenido relevante. GetStaticProps puede simplemente recuperar contenido específico de la página.

Gracias @zeusdeux
Re:

En cuanto a su segunda pregunta, lo hace automáticamente. Ejecute el siguiente desarrollador y estará listo.

Si los caché en un módulo y luego cambio los datos en CMS, cómo se invalidará la caché y se volverá a ejecutar por dev , pero sin detener next.js y ejecutarlo nuevamente :)

Si los caché en un módulo y luego cambio los datos en CMS, cómo se invalidará la caché y se volverá a ejecutar por dev , pero sin detener next.js y ejecutarlo nuevamente :)

getStaticPaths solo se invoca en una compilación de producción, por lo que solo puede decirle al método de búsqueda que se almacene en caché en el estado del módulo cuando se lo llame desde esa función.

Oye, no he visto si alguien tiene el mismo problema que yo.

Digamos que tengo la misma página en varias rutas con unstable_getStaticProps :

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

El código fuente es el mismo para ambas páginas, por lo que no es necesario duplicarlo. Entonces, para el primer archivo que contiene código fuente con lógica, el segundo solo importa el primero como export { default } from './[city]'; .

Pero arroja un error de que los datos de getStaticProps no están definidos. Si copio el mismo código en ambos archivos, funciona.

@homoky necesitas volver a exportar los métodos:

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

He estado probando SSG, pero sin suerte.

¿Debería el siguiente código con v9.2.1 dar como resultado SSG?

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

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

export default Page

La salida de mi consola de next build muestra:

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 debe exportarse en lugar de adjuntarse al componente de la página, por ejemplo

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

@joostmeijles unstable_getStaticProps debe exportarse en lugar de adjuntarse al componente de la página, por ejemplo

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

Gracias, eso lo resuelve.

Si alguien quiere ver un ejemplo funcional de extremo a extremo de esto, creando páginas dinámicas (desde un CMS) con una ruta general y SSG, consulte https://github.com/agility/agilitycms-next-starter- ssg.

Me quedé perplejo un par de veces y pensé que esto podría ser útil para otros.

¿Cómo puedo acceder a las siguientes rutas de API durante la compilación con getStaticProps al implementar en zeit.co/now? La búsqueda isomórfica requiere una URL absoluta; localmente funciona con http: // localhost : 3000 pero no con la implementación actual (o lo hice mal 🤷‍♂️). ¿Algunas ideas?

Si estoy en lo cierto, las rutas de la API se implementarán como funciones sin servidor y supongo que no están listas durante el proceso de compilación.

Querrá llamar a la función de su ruta api directamente, ya que eso es mucho menos general que pasar por http.

Querrá llamar a la función de su ruta api directamente, ya que eso es mucho menos general que pasar por http.

¿Algún recurso que pueda leer en los documentos sobre ese tema? Estoy en medio de la migración a zeit.co/now :)

Tomado literalmente, importe y llame a la función:

import MyFunction from '../lib/somewhere'


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

Otra pregunta: ¿Será posible usar getStaticProps / getStaticPaths y getServerProps uno al lado del otro? Por ejemplo, si he renderizado previamente algunas páginas con SSG, pero si no se encuentra una en la caché de CDN, ¿recurrirá a SSR para generar la página a pedido?

getStaticProps recurrirá a SSR y agregará el resultado a la caché,

getStaticProps recurrirá a SSR y agregará el resultado a la caché,

@lfades , si te entiendo correctamente, estoy super 😍 al respecto, porque significa que puedo renderizar previamente algunas de las páginas populares, en lugar de buscar y generar varios miles de páginas antes de tiempo.

Pero solo para asegurarme de que lo entiendo ... Digamos que tengo una página de ruta dinámica /products/[productId].js . Si proporciono un getStaticProps , y un número limitado de resultados de getStaticPaths , entonces estás diciendo que si /products/123 no se encuentra en la caché de CDN (porque no estaba t en getStaticPaths ), volverá a SSR, ejecutará getStaticProps y luego almacenará en caché el resultado como una página estática.

Pregunta de seguimiento: ¿eso también funcionará si no proporciono un getStaticPaths en absoluto?

@flintinatux Sí y sí 👍

getStaticProps recurrirá a SSR y agregará el resultado a la caché

Esto es un problema porque no hay forma de hacer 404, ya que getStaticProps no permite cambiar el objeto res , ya sea 200 o 500 si hay un error durante la llamada a la función.

¿Está previsto que esto cambie?

@ davidbailey00 al crear sitios web estáticos, las páginas 404 ya no tienen el código de estado 404.

Por supuesto, si hago una exportación estática completa, no hay forma de hacer códigos de estado, ya que todo es solo un archivo. Estoy hablando de implementar sitios híbridos usando getStaticProps en ZEIT Now; parece que debería respetar getStaticPaths y servir páginas 404, en lugar de forzar la representación de todas las páginas que coinciden con una ruta dinámica independientemente de esto.

Sin embargo, no es solo así como funciona en Now, lo mismo en next start .

Sin embargo, repetiré lo que dije antes: esto es experimental y cualquier cosa puede cambiar de comportamiento.

Pero es posible servir páginas 404 con getServerProps o getInitialProps - si getStaticProps ignora getStaticPaths al considerar el código de respuesta, entonces es completamente inviable para cualquier sitio que se preocupe por buen SEO.

Probablemente introduciremos más formas de manejar los códigos de estado, pero tenga en cuenta que la mayoría de los sitios estáticos (por ejemplo, CRA) enrutan /* a index.html donde 404 sigue siendo 200.

Hola chicos, tengo una pregunta clara, estoy construyendo un sitio web simple usando el nuevo [unstable_]getStaticProps para SSG en algunas de las páginas. Todo está funcionando bien hasta ahora, con la excepción del amplificador .

Si una página contiene [unstable_]getStaticProps , entonces amp está deshabilitado. Aquí un ejemplo simple trabajando con la próxima v9.2.1 donde puede verificar 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;

¿Alguna ayuda para entender cómo hacer que las páginas SSG con datos y amp funcionen?

Hola, ¿qué tal si admitimos getStaticProps para App componente ( _app.tsx ), es decir, para casos como la obtención de datos comunes para todos los componentes de la página durante la etapa de compilación?

Hola, ¿qué tal si admitimos getStaticProps para App componente ( _app.tsx ), es decir, para casos como la obtención de datos comunes para todos los componentes de la página durante la etapa de compilación?

@ pkral78 Puedo decirte cómo me

Creé un diseño con el enfoque "Diseño como componente de orden superior (HOC)" (ya no está en los documentos de aprendizaje 🤷‍♂️).

De todos modos, creé un diseño como el siguiente (solo un ejemplo):

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;

Y luego, en la página en la que desea usar este enfoque, puede agregar simplemente el HOC (tiene que exportar explícitamente [unstable_]getStaticProps y el amplificador no funcionan juntos), pero encontré una "buena manera" de tener una solicitud de alto nivel y consultas SSG por página.

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;

Quisiera hablar con discreción si es un buen enfoque. En mi caso, estoy usando esta técnica para consultar los enlaces en el contenido principal y por página en los de las páginas. Espero que ayude.

@robertovg Tiene que exportar a nivel de módulo ya que el código está

@timneutkens ¿Podría proponer una mejor solución para este pequeño ejemplo ? Solo estaba tratando de tener "consulta SSG de nivel de diseño" y "consulta SSG de nivel de página" de alguna manera y pensé en este enfoque de diseño de HOC.

La principal restricción para mí fue "exportar [unstable_] getStaticProps" explícitamente que necesita tener en cada página para marcar como página SSG.

Realmente también agradecería más información sobre si amp + SSG será compatible, pregunté antes.

Gracias 🙏

@robertovg Primero, separe el diseño de los datos, para que el diseño compartido tenga algo simple como esto:

import Layout from '../components/layout'

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

export default Page

Y luego, por getStaticProps obtenga los datos compartidos utilizando un método de otro módulo, por lo que el ejemplo completo podría verse así:

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 Primero, separe el diseño de los datos, para que el diseño compartido tenga algo simple como esto:

import Layout from '../components/layout'

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

export default Page

Y luego, por getStaticProps obtenga los datos compartidos utilizando un método de otro módulo, por lo que el ejemplo completo podría verse así:

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

Veo y entiendo esta solución, pero el problema que intentaba plantear era cómo escalar el uso de datos compartidos.
Por ejemplo, si tiene un <Header /> que usa sharedData para obtener los enlaces y estos provienen de un CMS sin cabeza. Tienes que inyectar el <Header /> como hijo del <Layout /> con accesorios u otra solución. Y debe repetir la inyección <Header /> en todas las páginas que desea usar.

Con el enfoque HOC , simplemente agregaría <Header /> una vez en el HOC.

Por eso pensé que era un buen punto el planteado por @ pkral78 , para evitar la duplicación de código si es posible.

Por eso pensé que era un buen punto el planteado por @ pkral78 , para evitar la duplicación de código si es posible.

Estaba en mi mente. La página _app debe tener su getStaticProps que se llama una vez durante el renderizado de la primera página y luego pasar los props guardados a las siguientes páginas renderizadas. Pero sigo pensando si es un concepto adecuado.

No estoy seguro de si este tipo de cosas es un caso de uso previsto, pero no parece funcionar:

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

Incluso si no es un caso de uso previsto, registra un error que parece un poco sospechoso:

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

Editar:

Oh, está bien, se resuelve cuando lo hago

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

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

Esto se queja de que la ruta del archivo de importación es dinámica

El jueves 30 de enero de 2020 a las 00:29, Jan Potoms [email protected] escribió:

No estoy seguro de si este tipo de cosas
https://codesandbox.io/s/nifty-cache-jspqr es un caso de uso previsto, pero
no parece funcionar:

// /pages/[...slug].jsximport ReactDOMServer de "react-dom / server";
exportar función asíncrona unstable_getStaticProps ({params: {slug}}) {
// ¿Qué tan seguro es esto?
const filePath = "../content/" + slug.join ("/") + ".mdx";
const {predeterminado: Componente} = esperar importación (ruta de archivo);
contenido const = ReactDOMServer.renderToStaticMarkup (Componente);
regreso {
props: {title: slug.join (""), content}
};
}
Exportar página de función predeterminada ({título, contenido}) {
regreso (


{título}




);
}

Incluso si no es un caso de uso previsto, registra un error que parece un
un poco sospechoso:

[advertir] ./pages/[...slug].jsx
Dependencia crítica: la solicitud de una dependencia es una expresión

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/zeit/next.js/issues/9524?email_source=notifications&email_token=AAADKRKOL34WKTG7J5QFRJ3RAIGPBA5CNFSM4JRPBEL2YY3PNVWWK3TUL52HS4DFVREXH63JSMVBWX ,
o darse de baja
https://github.com/notifications/unsubscribe-auth/AAADKRIWNA2DSMWFRGD453DRAIGPBANCNFSM4JRPBELQ
.

Por eso pensé que era un buen punto el planteado por @ pkral78 , para evitar la duplicación de código si es posible.

Estaba en mi mente. La página _app debe tener su getStaticProps que se llama una vez durante el renderizado de la primera página y luego pasar los props guardados a las siguientes páginas renderizadas. Pero sigo pensando si es un concepto adecuado.

@ pkral78 , podría deberse a que en la mayoría de los sitios SSG que imagino implementados con Next, me gustaría tener una "pieza común" (Encabezado, Pie de página, Barras laterales ...). Y por qué no hacer la consulta para esa pieza común en la _app si es necesario, y tenerla disponible en las páginas secundarias sin tener que hacerlo manualmente en cada página.

Mi única preocupación es que si lo pones en _app.js , no podríamos tener más de una "pieza común" dependiendo de la página. Con la idea de que estaba creando un prototipo, quería poder tenerlo en el diseño porque nos permitiría tener varios diseños según el tipo de página que desee representar, "por eso llamé withSSGLayout a mi HOC porque estaba planeando tener no solo páginas SSG sino SSR y páginas totalmente basadas en clientes, o incluso más de un SSGLayout. Esto podría hacerse si Layouts también pudiera ser responsable de un método padre getStaticProps .

De todos modos, tener SSG en Next lo convertirá en la herramienta para cualquier tipo de sitio web 🙌

@Janpot con respecto a https://github.com/zeit/next.js/issues/9524#issuecomment -580012327

Puedo recomendar encarecidamente que nunca use rutas dinámicas en import() . Empacará todos los archivos posibles debajo de la ruta en el paquete JS y reducirá en gran medida el rendimiento de la compilación al hacerlo.

@timneutkens Seguro, tiene sentido. ¿ getStaticProps solo está destinado a consultar API externas, no al sistema de archivos?

@Janpot puede leer desde el sistema de archivos, aunque a menudo terminará consultando alguna API externa.

@timneutkens Ok, es mejor usar @mdx-js/runtime entonces, en lugar de confiar en @next/mdx , supongo.

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 ¡sí! también puede usar el markdown simple, eso es lo que hacemos para nextjs.org/docs.

Con respecto a https://github.com/zeit/next.js/issues/9524#issuecomment -580207073, es exactamente como utilizo actualmente Next con SSR. Tengo una solicitud GraphQL que se realiza en el nivel de diseño y su contenido se comparte con los componentes comunes de la aplicación (barra de navegación, pie de página y los elementos secundarios dinámicos). Luego, los elementos secundarios dinámicos suelen realizar otra solicitud GraphQL de contenido específico de la página.

Por lo tanto, tener una forma de reutilizar esto parece importante, no me gustaría tener que duplicar el código en cada página para obtener esos datos comunes.

¡Oye!
Soy bastante nuevo aquí. Acabo de empezar a trabajar en la migración de la aplicación a NextJS.

Existe un caso de uso básico que se beneficiaría enormemente de esta función: versiones en varios idiomas. La aplicación web en la que estoy trabajando tiene versiones en 16 idiomas con más de 100.000 visitas a la página al día y poder generar de forma estática, por ejemplo, una página de destino sería fantástico, pero el problema es el enrutamiento.

Con la representación del lado del servidor, puedo leer los encabezados de las solicitudes o las cookies y representar la versión del idioma adecuada, pero sin ella, ¿es la única solución para crear rutas para cada versión como / en, / de, / fr y en "/" hacer que NextJS simplemente redireccione?

Después de aprender acerca de ReactDOMServer.renderToStaticMarkup lo agregué a mi función unstable_getStaticProps y descubrí que mejoró mi puntaje de PageSpeed ​​(móvil) de 96 a 100 gracias a la mejora drástica del tiempo para interactuar y el retardo máximo de primera entrada potencial .

Puedo visitar la página sin JavaScript y se carga bien, por lo que parece que React está trabajando en la carga de la página, a pesar de usar SSG.

Tal vez esto sea una falta de mi comprensión sobre React, pero esperaría que el rendimiento con y sin JavaScript sea el mismo, y no esperaría que el procesamiento previo de los componentes ayudara (pensé que eso es lo que SSG estaba haciendo).

¿Es lo esperado, un error o algo que estoy haciendo mal?

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

@JosephDuffy

por lo que parece que React está trabajando en la carga de la página, a pesar de usar SSG.

Está hidratando el DOM. Básicamente:

  1. su navegador carga el SSR html en el DOM del navegador
  2. React reconstruye todo el DOM virtual
  3. React atraviesa estos DOM y los sincroniza (hidratación)

Si su contenido es verdaderamente estático, sin efectos secundarios ni controladores de eventos, los pasos 2 y 3 son algo innecesarios. Con su método, básicamente reduce su árbol de componentes a 1 componente con 1 atributo, lo que es muy rápido para que React renderice e hidrate. (+ dangerouslySetInnerHTM se ignora durante la hidratación)

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

Tenga en cuenta que los controladores de eventos y los efectos secundarios no funcionarán con este método.

Editar:

Una idea podría ser permitir la omisión de la exportación predeterminada en una página si getStaticProps devuelve html estático. es decir

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

Dado que no es necesario representar nada en el lado del cliente, next.js puede excluir su tiempo de ejecución de la página y simplemente incluir el html que getStaticProps devolvió. Y funcionaría de la misma manera que si se usara dangerouslySetInnerHTML en el nodo raíz next.js.
Supongo que sería más fácil de implementar que la hidratación parcial, aunque menos potente. Reutilizar la terminología de React aquí podría reducir la confusión sobre cómo funcionaría esta característica.

Estoy intentando migrar un sitio estático a Next.js y me gustaría redirigir todas las variantes .html de publicaciones de blog a versiones que no terminan en .html. Parece que getStaticProps actualmente no obtiene contexto, por lo que no puedo realizar una verificación de slug y redireccionamiento entrantes. Sería útil si getStaticProps tuviera un contexto completo para poder hacer algunas cosas condicionales con él.

@nodabladam parece que estás buscando la RFC de rutas personalizadas: # 9081.

Ese RFC le permitiría definir algo como esto:

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

Actualmente puede probar esta función con la tecla experimental :

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

Implementé getStaticProps y getStaticPathNames en un proyecto mío (alrededor de 8K páginas).

Sin embargo, los archivos de salida se cuentan para el límite de 10K de archivos por implementación. Con 8K páginas, obtiene 16K de archivos de salida, ya que cada página también obtiene un archivo json.

¿Hay planes para aumentar este límite? ¿O puedo evitar este límite?

Tengo el mismo problema.
Entiendo que están buscando levantar ese límite, pero no sé cuándo se implementará.

Entonces uso getStaticProps en todas las páginas y getStaticPaths solo en algunas de ellas y funciona (mi página de producto genera el 70% del total de páginas, así que no puse ningún getStaticPaths en ella). Me mantengo por debajo del límite pero no es perfecto, la primera carga es bastante larga y difícil de manejar los errores 404.

Tengo el mismo problema.
Entiendo que están buscando levantar ese límite, pero no sé cuándo se implementará.

Entonces uso getStaticProps en todas las páginas y getStaticPaths solo en algunas de ellas y funciona (mi página de producto genera el 70% del total de páginas, así que no puse ningún getStaticPaths en ella). Me mantengo por debajo del límite pero no es perfecto, la primera carga es bastante larga y difícil de manejar los errores 404.

Espero que aumenten el límite pronto, sin embargo, espero que no sean 20K ... eso no será suficiente para mí a largo plazo.

Quiero evitar los primeros tiempos de carga con getStaticPaths. Puede que tenga que buscar otras soluciones además de Zeit Now.

Next.js también expondrá automáticamente un punto final de API que devuelve el resultado de llamar a getServerProps. [...] Next.js buscará este punto final de API expuesto para obtener los datos JSON que se convierten en los accesorios necesarios para representar la página del lado del cliente.

Next.js obtendrá datos de este punto final antes de realizar el cambio de ruta real y renderizar el componente de la página (no puede, al menos de forma predeterminada, hacerlo de otra manera). Por lo tanto, el usuario puede experimentar un sitio extremadamente ágil debido a que ciertas páginas se generan estáticamente, pero si hace clic en un enlace a una página SSR, de repente el sitio se "colgará" un poco antes de que cambie la ruta.

¿Existe una forma recomendada de cargar el componente _primero_ para que pueda llenarse con indicadores de carga, marcadores de posición animados, etc.? (En lugar de agregarlos a la página actual). Si no es así, ¿podría ser relevante para las características recientemente propuestas? Lo logré usando una combinación de getInitialProps y ganchos dentro del método de render, pero se siente desordenado.

Creo que muchos (¿la mayoría?) Prefieren este patrón de UX (cambio de página instantáneo), pero todavía no he visto ningún ejemplo de él con Next.js. Solo he usado el marco durante un par de días, así que corríjame si me equivoco.

¡Realmente entusiasmado con las nuevas funciones! Gracias por tu trabajo.

@nicoqh , sus preocupaciones sobre las transiciones de página no son específicas de SSG, ya que el bloqueo se produce con el actual getInitialProps . Utilizo nprogress para mostrar al menos una barra de progreso en la parte superior mientras se carga la página siguiente, pero también veo este ejemplo de transiciones de página legítimas que suenan más cerca de lo que estás describiendo. No lo he probado yo mismo, pero espero que te ayude con lo que necesitas:
https://github.com/zeit/next.js/tree/canary/examples/with-next-page-transitions

Parece que el archivo json /_next/data/BUILD_ID/<file>.json que se devuelve no respeta el assetPrefix. Esto hace que el archivo sea 404 para mí en mi entorno de producción, ya que tengo una configuración que espera que todo _next sea un activo que pase por CDN. Estos archivos json deberían en última instancia enrutarse a través del assetPrefix (CDN), ¿verdad?

Tengo el mismo problema.
Entiendo que están buscando levantar ese límite, pero no sé cuándo se implementará.
Entonces uso getStaticProps en todas las páginas y getStaticPaths solo en algunas de ellas y funciona (mi página de producto genera el 70% del total de páginas, así que no puse ningún getStaticPaths en ella). Me mantengo por debajo del límite pero no es perfecto, la primera carga es bastante larga y difícil de manejar los errores 404.

Espero que aumenten el límite pronto, sin embargo, espero que no sean 20K ... eso no será suficiente para mí a largo plazo.

Quiero evitar los primeros tiempos de carga con getStaticPaths. Puede que tenga que buscar otras soluciones además de Zeit Now.

@erhankaradeniz y @ziltosh , deberíamos implementarlo en general muy pronto. Si desea obtener ayuda con eso lo antes posible, puede enviarme un ping directamente o [email protected] y ellos lo resolverán.

Tengo el mismo problema.
Entiendo que están buscando levantar ese límite, pero no sé cuándo se implementará.
Entonces uso getStaticProps en todas las páginas y getStaticPaths solo en algunas de ellas y funciona (mi página de producto genera el 70% del total de páginas, así que no puse ningún getStaticPaths en ella). Me mantengo por debajo del límite pero no es perfecto, la primera carga es bastante larga y difícil de manejar los errores 404.

Espero que aumenten el límite pronto, sin embargo, espero que no sean 20K ... eso no será suficiente para mí a largo plazo.
Quiero evitar los primeros tiempos de carga con getStaticPaths. Puede que tenga que buscar otras soluciones además de Zeit Now.

@erhankaradeniz y @Ziltosh , deberíamos implementarlo en general muy pronto. Si desea obtener ayuda con eso lo antes posible, puede enviarme un ping directamente o [email protected] y ellos lo resolverán.

Gracias @kvangundy
Me he puesto en contacto contigo en Twitter con respecto a este problema ;-)

@erhankaradeniz ¿Puede enviar un correo electrónico a [email protected] en su lugar? De esa forma termina correctamente en nuestro sistema.

@flintinatux , gracias por el

Supongo que no se abordará en este tema, lo que significa que está fuera de tema, así que buscaré otro lugar para discutirlo :)

¡Creo que el enfoque de dividir getInitialProps en getStaticProps & getServerProps es mucho más limpio! Tengo una pregunta sobre cómo esto afecta nuestro caso de uso:
Queremos crear 2 compilaciones separadas: una versión estática para nuestro sitio de producción y una versión que usa SSR para un entorno de edición.

Estaba pensando que podría adjuntar condicionalmente getStaticProps vs getServerProps como métodos estáticos dependiendo de la compilación (similar a https://github.com/zeit/next.js/issues/9524#issuecomment- 558617056), pero no estoy seguro de si esto será posible exportarlos condicionalmente como están. ¿Alguna idea de si esto será posible para soportar dinámicas / estáticas dependiendo de la compilación?

Con respecto a:

RFC se actualizará para reflejar los cambios más adelante, aún iterando sobre el uso en el mundo real en nuestras aplicaciones.

Me pregunto si hay una manera de usar algún tipo de ruta comodín para capturar rutas que se desconocen en el momento de la construcción. Es increíble que pueda representar páginas estáticas a partir de, por ejemplo, datos de CMS, pero ¿qué pasa si alguien agrega un nuevo elemento? No tengo una página estática para eso. Este problema me rasca la cabeza durante mucho tiempo.

He configurado una ruta dinámica para representar páginas estáticas _páginas / [slug] .js_. _getStaticPaths_ está obteniendo todas las páginas que quiero representar estáticamente. Tengo _getStaticProps_ para consultar los datos y pasarlos a la función de renderizado. Todas las páginas dadas en _getStaticPaths_ se representan como archivos HTML dentro de _.next/server/static_ en la compilación. ¡Excelente!

Ahora ejecuto npm run start y estas páginas como deberían. Pero solicitar una URL faltante (como _ / foo_) genera nuevos archivos HTML y JSON estáticos dentro de _.next/server/static_. Esto no está bien. ¿Cómo puedo hacer que el servidor redirija todas las demás URL a _pages / _error.js_?

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

También cubrimos eso.

Ahora ejecuto npm run start y estas páginas como deberían. Pero solicitar una URL faltante (como / foo) genera nuevos archivos HTML y JSON estáticos dentro de .next / server / static. Esto no está bien. ¿Cómo puedo hacer que el servidor redirija todas las demás URL a pages / _error.js?

Esto todavía es un comportamiento en vuelo y no inesperado a partir de ahora.

Nuevamente, un recordatorio de que está utilizando una función experimental y el comportamiento pueden cambiar en cualquier momento. Las cosas cambiarán y potencialmente se romperán entre todas las versiones mientras usa esto cuando no es estable.

@timneutkens ¡Gracias! Entiendo la inestabilidad. ¿Tienes idea de cómo gestionar esto? Revisé el código y noté que arrojar un error dentro de _unstable_getStaticProps_ genera la página de error. Esta podría ser una buena manera de hacerlo. Solo necesitaría una forma de pasar el error a las _pages / _error.js_. Me gustaría enviarlo 404. Ahora va como 500.

He publicado esto un montón de veces antes en otros hilos, pero "going to _error" es un comportamiento inesperado, a partir de ahora su página debería mostrar un estado 404. Simplemente dijo if(!data.something) { return <My404Component /> } , y luego My404Component debería establecer noindex metaetiquetas.

¿En serio? La documentación indica claramente cómo usar _pages / _error.js_ para los 404.

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

@ jiv-e eso es para 404 causados ​​por:

  • Página no encontrada
  • Archivo no encontrado

Si tiene rutas dinámicas, debe manejar el caso "404" como dije, por ejemplo, como https://nextjs.org/docs/advanced-features/custom-error-page#reusing -the-built-in-error- página

¡Entiendo! ¡Gracias!

Me gustaría usar getStaticProps para buscar claves de traducción / idioma en el tiempo de compilación porque lo más probable es que cambien 1-2 veces al mes o incluso al año. Tampoco los necesita como JSON / props dentro del DOM. El problema es que no quiero pasar claves por el árbol al componente donde realmente las uso. ¿Qué enfoques son adecuados para mi caso de uso?

useTranslation () hook (o HOC) con contexto?

Sería bueno si AppTree fuera parte del contexto NextGetStaticProps ( getStaticProps({ AppTree }) ). De lo contrario, no será posible ejecutar cosas como apolos getDataFromTree en ssg.

En este punto, no planeamos permitir el recorrido de AppTree en getStaticProps, ya que es realmente malo para el rendimiento (comentarios constantes de las empresas). Cuando agrega getStaticProps a una página, todavía pasa por getInitialProps de _app para permitir la adopción incremental, por lo que aún funcionaría con Apollo realmente.

Sería bueno si pudiéramos tener la funcionalidad amp: 'hybrid' y SSG al mismo tiempo.
Esto podría lograrse creando dos archivos para una página como esta, es decir:

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

Esto permitiría que los proxies se resuelvan en un documento de amplificador basado en el parámetro de consulta ?amp=1 .

Sería bueno si pudiéramos tener la funcionalidad amp: 'hybrid' y SSG al mismo tiempo.
Esto podría lograrse creando dos archivos para una página como esta, es decir:

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

Esto permitiría que los proxies se resuelvan en un documento de amplificador basado en el parámetro de consulta ?amp=1 .

Exactamente @Dacturne , este es el único inconveniente que veo para comenzar a usar SSG ya en proyectos como comentaba en este hilo hace tiempo.

🤞

@jansedlon Hice una publicación en el blog respondiendo a tu pregunta:

Me pregunto si hay una manera de usar algún tipo de ruta comodín para capturar rutas que se desconocen en el momento de la construcción. Es increíble que pueda representar páginas estáticas a partir de, por ejemplo, datos de CMS, pero ¿qué pasa si alguien agrega un nuevo elemento? No tengo una página estática para eso. Este problema me rasca la cabeza durante mucho tiempo.

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

(no publico aquí porque es demasiado grande)

@ ivan-kleshnin ¡He echado un vistazo rápido y parece súper emocionante! ¡Es posible que me hayas ahorrado cientos de horas! Muchas gracias, hoy echaré un vistazo más a fondo.

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

@jansedlon, como se dijo anteriormente, estamos trabajando en algo con respecto a esto que no está cubierto en la publicación de blog de @ ivan-kleshnin. Espero poder compartir más sobre esto muy pronto.

@timneutkens Me encantan los cambios hasta ahora 🙏 ¿Tiene algún plan para mejorar / apoyar la internacionalización estática + completa?

Hemos estado usando las nuevas API getStaticProps / getStaticPaths en nuestra migración de tinacms.org de Gatsby a Next.js, ¡y hasta ahora ha sido genial!

Un obstáculo que hemos tenido es la generación de una fuente RSS. Lo ideal sería generarlo estáticamente, ya que el contenido al que hace referencia se genera estáticamente. No veo una forma de hacer esto actualmente, así que en su lugar lo estamos manejando en el lado del servidor consultando el contenido y escribiendo XML en la respuesta.

¿Ha habido alguna discusión sobre la compatibilidad con la generación estática para tipos de contenido que no son HTML?

Para su información, comenzamos a usar getStaticProps en zeit ahora y lanzamientos usando la bandera --prod y no se estaba borrando el caché para los archivos json en los nuevos lanzamientos. El cambio de nuestra versión de producción al uso de la función de alias funcionó y se borró la memoria caché.

Hemos estado usando las nuevas API getStaticProps / getStaticPaths en nuestra migración de tinacms.org de Gatsby a Next.js, ¡y hasta ahora ha sido genial!

Un obstáculo que hemos tenido es la generación de una fuente RSS. Lo ideal sería generarlo estáticamente, ya que el contenido al que hace referencia se genera estáticamente. No veo una forma de hacer esto actualmente, así que en su lugar lo estamos manejando en el lado del servidor consultando el contenido y escribiendo XML en la respuesta.

¿Ha habido alguna discusión sobre la compatibilidad con la generación estática para tipos de contenido que no son HTML?

Lo estaba pensando por mí mismo y acabo de enterarme de esto. Aquí están mis guiones:

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

Antes next build se llama yarn sitemap que genera un mapa del sitio estáticamente. Puede usar la misma técnica, para almacenar en caché todos los datos en json, por ejemplo, que necesitará en getStaticProps y puede reutilizarlos en varias páginas.

Se actualizó el RFC, se modificó un poco el comportamiento de getStaticPaths (debe devolver una clave paths ahora, esto refleja getStaticProps donde props deben devolverse. el cambio aún no ha llegado a Next.js.

También se agregó una explicación para el comportamiento fallback (generación en segundo plano a pedido de páginas que no se exportaron en el momento de la compilación).

Hice otra actualización del RFC, agregué una explicación de los cambios en la navegación del cliente con respecto a un estado Loading .

Es posible que deseemos agregar una forma para que los usuarios sepan si el estado de carga se representa a través de un gancho de React 🤔

¡Buena cosa! Me preguntaba, ¿habría una manera de que las páginas generadas estáticamente compartan datos entre múltiples rutas usando un solo archivo JSON (como la división de código pero para datos)?

Subí a la última compilación canary e inmediatamente me mordió el nuevo estado Loading . En el pasado, era bueno asumir con seguridad que ya tengo los datos correctos antes de que la capa de vista comience a renderizarse. La carga asincrónica forzada es una gran desviación de eso. Realmente disfruté arrancando todos los puntos finales estándar que reemplazarán los nuevos puntos finales SSR generados automáticamente, pero no estaba planeando rediseñar cada página para incluir nuevos estados Loading .

Entiendo el deseo de un TTFB más rápido y, en el futuro, eso podría ser bueno para mi aplicación. Pero, ¿sería posible convertir el estado Loading una función de inclusión o exclusión voluntaria, similar a fallback: false por getStaticPaths ? Quizás un export const enableLoadingState = false en la página, o en todo el sitio en el next.config.js .

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

Nuevamente, un recordatorio de que está utilizando una función experimental y que estamos experimentando con el comportamiento actualmente.

Implementé mi sitio web SSG (experimental) en Now (usando una configuración predeterminada). Funciona bien, pero veo errores 404 en la pestaña de red cuando navego por el sitio. Todos los errores 404 apuntan a _next/static/pages/[slug].js .

¿Es este comportamiento esperado mientras es experimental? ¿O debería cambiar algunas configuraciones?

@joostmeijles , parece que no está proporcionando los href y as correctos a next/link . Para páginas dinámicas, href debe ser la página href='/[slug]' y as debe ser la URL as='/slug-1'

Recibo 3 registros en la consola durante la compilación, ¿es un error?

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

No, eso se espera según fallback en el RFC.

No, eso se espera según fallback en el 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" } },
        ]
    }
}

Intenté excluirme, pero recibo este error.

Error: claves adicionales devueltas de unstable_getStaticPaths en / [año] (respaldo) El único campo permitido actualmente es paths

Nuevamente, un recordatorio de que está utilizando una función experimental y que estamos experimentando con el comportamiento actualmente y no todo está implementado.

¿Esta función getStaticProps solo estará disponible para las páginas?
¿Sería interesante para la aplicación / documento también, por ejemplo, buscar alguna configuración global para la aplicación?

He implementado esto "con éxito" y estoy contento con los resultados hasta ahora ... pero me pregunto si hay alguna forma de hacer que las compilaciones posteriores sean "más rápidas". Por ejemplo, compruebe si las páginas generadas por SSG no han cambiado y no las vuelve a generar. (Probablemente una ilusión mía)

@timneutkens ¿Tiene planes de agregar un generador sitemap.xml para las páginas SSG? Ni siquiera estoy hablando de rutas dinámicas, ya que creo que es más fácil implementarlo solo para páginas estáticas por ahora.

@timneutkens ¿Tiene planes de agregar un generador sitemap.xml para las páginas SSG? Ni siquiera estoy hablando de rutas dinámicas, ya que creo que es más fácil implementarlo solo para páginas estáticas por ahora.

Sí, esta sería una gran opción. Actualmente generando uno yo mismo con SSR. (pero el archivo sitemap.xml tarda mucho en cargarse)

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

Inicialmente solo para páginas porque habrá otro trabajo que afectará a getStaticProps después de que aterrice.

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

Sí, pero no como parte de este RFC. Habrá un seguimiento después de estas tierras.

@timneutkens Creo que la implementación de las páginas SSG es fácil porque puede insertar un URI en una matriz cada vez que Next crea una página estática y luego, cuando termina, simplemente asigna la matriz a cada etiqueta XML, únala e insértela en el medio de una etiqueta <sitemapindex> . El getStaticProps podría tener otra clave en el objeto de retorno llamado excludeFromSitemap por lo que el valor predeterminado sería que todas las páginas se incluyan en el sitemap.xml pero con la opción de excluirse.

Si ese fuera el caso, los desarrolladores tendrían un control preciso sobre qué página estática entraría en el mapa del sitio (por ejemplo: si la función [foo] de la página getStaticPaths devuelve rutas con foo params 'abc' y 'xyz' pero solo el archivo 'abc' debe estar en el mapa del sitio, el desarrollador podría establecer excludeFromSitemap en true si el parámetro ==='xyz' en getStaticProps .

Además, para SSR y páginas estáticas, podría ser posible exportar una constante (es decir, export const excludeFromSitemap = true; ) del archivo de página, como getServerProps , getStaticPaths y getStaticProps se exportan.

En las páginas SSG, si hay una constante exportada excludeFromSitemap (página predeterminada) y esa clave también está en el objeto devuelto por la función getStaticProps (ruta específica), el valor exportado debería actuar como predeterminado valor para todas las rutas en esa página y la ruta específica excludeFromSitemap , cuando está presente en el objeto getStaticProps , debe anular el valor predeterminado de la página (por lo que una página podría hacer export cosnt excludeFromSitemap = true y luego agregue la clave excludeFromSitemap al objeto devuelto de getStaticProps con valor false para excluir todas las rutas del mapa del sitio excepto esa específica).

El código para agregar a la matriz sería algo como esto (calculé la tabla de verdad y obtuve la expresión booleana mínima con un mapa 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);

Convertir la matriz en el mapa del sitio sería tan fácil como hacer esto (asumiendo que los URI en la matriz ya están codificados y filtrados por !excludeFromSitemap ):

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

Creo que esta característica encajaría muy bien en Next.JS porque parte de su misión es dar a los usuarios la puntuación de 100 SEO y tener un sitemap.xml sería de gran ayuda! ( robots.txt también podría generarse potencialmente agregando un else a la condición que agrega las rutas a la matriz del mapa del sitio para agregar esa ruta a otra matriz de páginas no permitidas)

En la versión de lanzamiento actual, cuando se usa la función unstable_getStaticPaths junto con la función unstable_getStaticProps , no se pueden realizar llamadas de API a funciones que viven en /api/ .
Como el servidor no se está ejecutando, es imposible realizar las solicitudes correspondientes y generar los props estáticos de esta manera.
O no tiene que proporcionar las funciones de rutas (lo que básicamente hace que este SSR tenga un caché, ¡lo cual sigue siendo bueno!) O confiar en SSR en lugar de SSG.

¿Quizás esta sería una buena adición para esta función? No estoy seguro de cuál sería la mejor manera aquí, he leído una propuesta en otro lugar, que sugería atajar la solicitud http, con SSR y rutas /api , esto también sería útil aquí.

Pero todo esto, por supuesto, significaría ejecutar código en el entorno de compilación, lo que haría llamadas a otros servicios / llamadas a la base de datos o similares. Esto debería quedar claro cuando se implemente, pero sería una buena adición para esta función.

@reckter Sí, acabo de hacer algo similar yo mismo. Tuve que conectarme a mi base de datos para cada solicitud de página separada mientras se generaban estáticamente. Me sentí muy extraño ...

Espero que ese no sea el caso de uso final.

Sería bueno tener algún tipo de script de inicialización que pueda configurar desde el next.config o algo ...

@reckter ¡ Una forma de

De todos modos, una posible solución para acceder a las rutas API durante SSG sería tener un servidor local que solo ejecute las rutas /api antes de compilar las páginas estáticas. Entonces los pasos de compilación serían:

  1. Inicie un servidor (tal vez llamado "servidor de compilación api" o algo así) que solo sirva las rutas /api
  2. Ejecutar unstable_getStaticPaths
  3. Ejecutar unstable_getStaticProps
  4. Compila las páginas estáticas

@reckter básicamente no tiene que llamar a las rutas API, puede llamar a la función que implementa directamente, esto también evita muchos de los gastos generales relacionados con las causas http.

Básicamente, si actualmente tiene una ruta API que se ve así:

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

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

Lo cambiarías a:

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

Y luego en tu página:

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

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

Sería complicado hacer lo mismo con las API GraphQL. Y también para la mayoría de REST.

¡Llamada a la API! = Obteniendo de DB (en general)
Casi siempre hay algo de lógica empresarial en la capa de API como cambio de nombre de campo, reformateo de datos, etc.

Estoy seguro de que tiene razones para rechazar las llamadas pages/api ... pero eludir la API real no será fácil ni barato. Y un par de milisegundos ahorrados no compensarán las tarifas por código / complejidad adicional, en mi opinión.

También se siente extraño que se permitan solicitudes a cualquier API. Excepto el tuyo 🤷‍♂

el uso de unstable_getStaticPaths hace que la página se recargue, perdiendo el estado actual en redux, por ejemplo. ¿Cambiará este comportamiento en el futuro?

editar: parece que este comportamiento se puede eludir usando la opción as en enlaces o enrutador

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

@meesvandongen siempre fue así. Si su <Link> no es válido, lo lleva a la parte de backend, que básicamente funciona como <a> . Los fragmentos dinámicos como [key] deben emparejarse con los valores correspondientes.

@reaktivo pages/[lang]/blog/[id].js -> en getStaticPaths proporciona todas las URL para renderizar estáticamente.

https://github.com/zeit/next.js/issues/9524#issuecomment -562625858
en este caso, debe agregar la función getStaticPaths y getStaticProps para cada página excepto index.js.
Si hay algunas páginas mdx, el proyecto es más difícil de mantener.

considere cambiar o ser compatible con métodos getStaticPaths getStaticProps estáticos. https://github.com/zeit/next.js/issues/9524#issuecomment -558617056
Si es así, la página se puede ajustar mediante una función de orden superior o un componente de orden superior (HOC).
De esta forma, el código es más fácil de mantener y más conveniente para mecanografiar.


temblor de árboles vs dinámico. Qué dolor de cabeza.

Con 9.2.3-canary.13 intenté usar fallback: false en getStaticPaths así:

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

pero falla con el siguiente error:

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

Con 9.2.3-canary.13 intenté usar fallback: false en getStaticPaths así:

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

pero falla con el siguiente error:

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

Creo que necesita el mapa un nivel más alto, por lo que el mapa devuelve el objeto que tiene actualmente, pero con una babosa única. en lugar de mapear los caminos.

Todavía no he actualizado mi versión en nextjs, pero debería ser similar:

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

@jorngeorg es un PR abierto: https://github.com/zeit/next.js/pull/10701

¡Fantástica contribución! Realmente mejora el proceso de renderizado estático.

Recomiendo agregar a los documentos que en rutas dinámicas, el "respaldo" se generará sin ninguna llamada a getStaticProps , lo que significa que debe codificar su componente para tener en cuenta el caso en que los accesorios están vacíos.

Alternativamente, puede cambiar el comportamiento para llamar a getStaticProps sin contexto al crear el respaldo. Esto sería coherente con el funcionamiento actual de next export (por ejemplo, /p/[id].js se exporta a /p/[id].html ejecutando su getInitialProps sin contexto).

  • getStaticProps - Optar por la generación estática (SSG) en next build tiempo.
  • getServerProps - Optar por el renderizado del lado del servidor (SSR) que renderiza bajo demanda.

10722

Cambie el nombre de getServerProps por getServerSideProps.

Recomiendo agregar a los documentos que en rutas dinámicas, el "respaldo" se generará sin ninguna llamada a getStaticProps , lo que significa que debe codificar su componente para tener en cuenta el caso en que los accesorios están vacíos.

¡Buen punto para mencionarlo! También tuve algunos errores de compilación / implementación porque me lo perdí.

Se actualizó el RFC para reflejar los cambios.

@timneutkens

  • La solicitud posterior a la misma ruta servirá la página generada

Supongo que esto significa que Next.js almacenará en caché la página generada. ¿Es esto un caché en memoria? ¿Esta caché está limitada por límites o puede provocar pérdidas de memoria?

Cuando usa next start , usa lru-cache similar al ejemplo actual de almacenamiento en caché, actualmente el límite predeterminado es 50 MB, podríamos configurarlo más adelante: https://github.com/zeit/next.js/ blob / canary / packages / next / next-server / server / spr-cache.ts # L90

Cuando hospeda en ZEIT Now, la generación y el almacenamiento en caché ocurren en el CDN / Proxy, por lo que funciona de manera ligeramente diferente y nunca tendrá que preocuparse por las pérdidas de memoria o si está superando el límite de lru.

👍 ok, parece razonable. Eso es más o menos lo que tenía en mente como un comportamiento predeterminado sensato.

  • getStaticProps - Optar por la generación estática (SSG) en next build tiempo.
  • getServerProps - Optar por el renderizado del lado del servidor (SSR) que renderiza bajo demanda.

10722

Cambie el nombre de getServerProps por getServerSideProps.

Sin embargo, ¿por qué el cambio de nombre? En mi humilde opinión, getServerProps es lo suficientemente preciso y más corto de escribir, agregar Side me parece redundante.

Me preguntaba si se han realizado cambios en el método getStaticPaths. Mis páginas dinámicas ya no se generan como páginas estáticas, ¿ahora se exportan como funciones lambda?

¿Estoy en lo cierto cuando el comportamiento predeterminado ahora es que las páginas se representan primero como lambda y solo después de visitar una página específica, la página se genera en una página estática? (como se menciona en el respaldo)

@erhankaradeniz No se han realizado cambios en getStaticPaths que den como resultado que sus páginas sean Lambdas. Es probable que se trate de un error de uso.

¿Puede mostrar su código para que podamos identificar el problema?

@Timer por ahora he vuelto a [email protected] donde todavía puedo usar params, hasta que

así es como actualmente generé mis caminos:

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

y en otra pagina hago:

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

no he logrado convertirlo a la nueva versión canary con las rutas. Debo estar haciendo algo mal, porque console.logs ni siquiera se activan dentro de getStaticPath

Tengo problemas con el procesamiento previo de rutas anidadas y 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("/"),
        }
      }
    }),
  }
}

lleva a

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.

para la página de inicio. Por alguna razón, NextJS no coincide

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

para

/[lang]/[...slugs]

Si proporciono {lang: "en", slugs: ["/"]} se compila pero con una URL incorrecta:

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

Para el registro, getServerSideProps funciona bien con una configuración similar.

Sé que es experimental, pero este hilo es para dar retroalimentación, ¿verdad?

pages/[lang]/[...slugs].js coincide con /en/abcdef y no /en , para eso actualmente tienes que crear pages/[lang]/index.js .

Hay una solicitud de función abierta para esto: https://github.com/zeit/next.js/issues/10488

Primero que nada, esto es asombroso. Esperaba tener algo como esto en Next.js para finalmente poder alejarme de Gatsby.js y tener una aplicación híbrida (estática + dinámica).

🚀 Probé el canario y la versión compleja de la aplicación a medio hornear funcionó bien. Confieso que no he leído todos los comentarios aquí, pero no estoy seguro de si la agitación de árboles se ha implementado todavía.

🤔 getStaticPaths parece mucho más a setStaticPaths donde estamos definiendo la ruta estática para el comportamiento de SSG. Eso me confundió un poco.

🧐 Me pregunto si podemos mejorar los tiempos de construcción al tener categorías de construcción. Sé que esto complicaría la configuración, pero valdrá la pena. Dejame explicar:

¿Qué pasa si tenemos algo como setBuildCategory que lo establece en blog o pages o lo que alguien quiera 2020-content ? Luego, el constructor de SSG busca la categoría de la página que se cambió y solo intenta reconstruir esa categoría a partir de una combinación de caché + nuevo renderizado. Algo como esto puede ayudarnos a hacer que SSG sea rápido y evitar grandes tiempos de compilación para cosas que no son propensas a cambiar mucho pero que aún podrían cambiar, por lo que no se pueden archivar.

Si eso tiene algún sentido; estoy feliz de saltar a una llamada y charlar sobre esto.

¿Cómo manejar getServerSideProps con una implementación de servidor personalizada?

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

En el ejemplo anterior, visitar /a mostrará la página pages/b.js . Pero una redirección del lado del cliente a /a intenta descargar el archivo a.json , que no existe en este caso.

¿Se supone que tenemos condiciones similares para las solicitudes de /_next/data/{BUILD_ID}/{PAGE}.json para representar diferentes archivos JSON?

Para usar fallback: true en getStaticPaths, ¿cómo obtengo el objeto req? Actualmente parece que no puedo. La razón por la que lo necesito es tomar algunas cookies del navegador para autenticar una ruta.

@tylermcrobert, ¿cómo te imaginas agarrar cookies cuando no hay ninguna solicitud?
Las rutas con backend que dependen de las solicitudes de visitantes reales no se pueden convertir en estáticas mediante definiciones de "estático" y "dinámico". No quiere decir que no pueda combinar estática y autenticación ... es solo que la parte de autenticación pertenecerá a la API y al código del cliente en lugar de a las páginas.

¿Cómo manejar getServerSideProps con una implementación de servidor personalizada?

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

En el ejemplo anterior, visitar /a mostrará la página pages/b.js . Pero una redirección del lado del cliente a /a intenta descargar el archivo a.json , que no existe en este caso.

¿Se supone que tenemos condiciones similares para las solicitudes de /_next/data/{BUILD_ID}/{PAGE}.json para representar diferentes archivos JSON?

Next.js admite parámetros de ruta dinámica, por lo que la reasignación en un servidor personalizado ya no es necesaria: https://nextjs.org/docs/routing/dynamic-routes

El enfoque que describió ya no funciona con <Link> (causaría una transición de página completa), por lo que getServerSideProps ya funciona.

@tylermcrobert, ¿cómo te imaginas agarrar cookies cuando no hay ninguna solicitud?
Las rutas con backend que dependen de las solicitudes de visitantes reales no se pueden convertir en estáticas mediante definiciones de "estático" y "dinámico". No quiere decir que no pueda combinar estática y autenticación ... es solo que la parte de autenticación pertenecerá a la API y al código del cliente en lugar de a las páginas.

Tal vez esté malinterpretando la opción de respaldo en ese caso. Lo que estás diciendo tiene mucho sentido en el contexto del tiempo de construcción.

¿No es fallback: true para cuando no hay una ruta predefinida? En ese caso, se alcanzaría un respaldo desde el navegador, ¿no?

@tylermcrobertfallback: true case tiene una solicitud pero la API tiene que estar unificada por el "mínimo común denominador". No puedo imaginar un sistema de trabajo donde todo se construya con un conjunto de premisas y luego se actualice gradualmente con un conjunto de premisas totalmente diferente. Será un desastre apoyar.

Creo que se pierde el punto de que esas compilaciones incrementales todavía se almacenarán en caché entre compilaciones. ¡Así que el papel del primer visitante influirá en el resultado de la compilación para todos los usuarios consiguientes! Suena mala idea.

@ ivan-kleshnin Lo entiendo y ciertamente estoy de acuerdo. La razón por la que pregunto es por mi caso de uso específico.

Estoy usando un CMS sin cabeza que permite la funcionalidad de vista previa, por lo que las páginas que deberán tener una vista previa no se incluirán en el momento de la compilación (porque la entrada que se está obteniendo una vista previa no existirá en este momento). Pensé que este era un caso en el que entraría la opción de reserva.

Para acceder a esa vista previa, necesito acceder a la referencia de vista previa de la API que se proporciona a través de una cookie.

¿Es este un caso en el que debería desechar useStaticProps completo? Odiaría perder el beneficio de las compilaciones estáticas porque no puedo obtener una vista previa de mis documentos.

El atractivo de este RFC sobre algo como Gatsby es que nos brinda un "control híbrido" con la generación de sitios estáticos que hace que sea menos complicado trabajar con CMS sin cabeza.

Estoy usando un CMS sin cabeza que permite la funcionalidad de vista previa, por lo que las páginas que deberán tener una vista previa no se incluirán en el momento de la compilación (porque la entrada que se está obteniendo una vista previa no existirá en este momento). Pensé que este era un caso en el que entraría la opción de reserva.

Estén atentos, más pronto 🕵

Entonces, si entiendo esto correctamente, podemos usar el respaldo verdadero cuando, por ejemplo, en mi caso, un usuario se registra (no se genera una página estática ya que es una nueva página / usuario) pero cuando el perfil recibe una visita, ¿se genera automáticamente?

Erhan Karadeniz
http://www.erhankaradeniz.com

El 4 de marzo de 2020, a las 20:25, Tim Neutkens [email protected] escribió:


Estoy usando un CMS sin cabeza que permite la funcionalidad de vista previa, por lo que las páginas que deberán tener una vista previa no se incluirán en el momento de la compilación (porque la entrada que se está obteniendo una vista previa no existirá en este momento). Pensé que este era un caso en el que entraría la opción de reserva.

Estén atentos, más pronto 🕵

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub o cancele la suscripción.

Los datos del usuario son un mal ejemplo, ya que querría obtener ese lado del cliente. El respaldo está ahí para las páginas que generan estáticamente bajo demanda y que no se han generado en el momento de la compilación. Por ejemplo, es posible que desee generar las 100 publicaciones de blog principales en el momento de la compilación y no generar otras con menos tráfico.

Pronto llegarán los documentos.

Sí, lo que quise decir fue una página de marcador de posición ... Buscaría datos de usuario en el lado del cliente de hecho.

@timneutkens ¿Habrá alguna forma de eliminar o reconstruir páginas específicas generadas estáticamente?

¡¡¡Hola!!! Suena como la aplicación óptima. ¡Me encanta React y Next! ¡Hizo todo tan elegante y simple para que lo usemos! Pero el ejemplo incluye la noción de blog. Me gustaría ver un ejemplo de una implementación al consultar un CMS sin cabeza y realizar la búsqueda por página / publicación como una exportación como un elemento estático.

// salud, ya que es cerca de viernes !!!

@timneutkens esto es emocionante 👌

Un escenario al que nos enfrentamos con frecuencia y todavía no tengo una solución perfecta con next.js o gatsby, excepto las rutas dinámicas o la generación de proyectos en un bucle:

Por razones históricas, tenemos que lidiar con múltiples dominios (y no tenemos ganas de cambiar esto) que sirven a las mismas páginas / páginas exactas con la excepción de precios, moneda, números de teléfono de soporte y selectores de idioma. Por naturaleza, la mayoría de esas páginas de marketing son bastante estáticas y sería suficiente crearlas diaria o semanalmente (en lugar de tener que renderizar en cada solicitud).

Mi pregunta / pensamiento: ¿ve una forma (en el futuro?) De que getStaticPaths pueda generar páginas basadas en algo que no es un parámetro de ruta pero que podría usarse en un nivel de solicitud para cambiar entre ellas (por ejemplo, sin servidor La función devuelve un resultado estático y prediseñado basado en locale )

Concretamente, esto significaría que https://mysite.com/my-product y https://mysite.co.uk/my-product servirían dos páginas estáticas diferentes, pero sin que tengamos que generar nuestra próxima aplicación 50 veces o tener que presionar un CMS en cada solicitud😅

Gracias de antemano y estoy ansioso por escuchar sus pensamientos, especialmente si eso es algo para el futuro que podría resolverse / solucionarse ❤️

Estoy pensando en un caso de uso en el que quiero usar SSG para páginas de destino de alto tráfico para SEO y para reducir la carga del servidor, pero aún quiero que los datos actuales se usen después de la hidratación y en el enrutamiento del lado del cliente a esta página. ¿Sería eso posible?

Básicamente, en el enrutamiento del lado del cliente a esta página, el comportamiento debería ser como getInitialProps (los datos actuales se obtienen antes de que la página sea visible). Y en el enrutamiento del lado del servidor a esta página, el html estático debe ser servido e hidratado, y luego (opcionalmente) algunas respuestas api obtenidas para actualizar algunos datos en la página.

Acabo de jugar con unstable_getStaticProps solo para probarlo y encontré un conflicto divertido: es difícil usar rutas API con getStaticProps .

No preste atención a la semántica del código, sino solo al flujo de obtención de datos:

// 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 creación de la página se bloqueará en el momento de la creación porque el servidor no se está ejecutando. No estoy seguro de si este es un caso de uso válido, ya que getStaticProps no debería usarse con nada demasiado dinámico, pero pensé que era un caso interesante para compartir (puedo imaginar totalmente un punto final de API de ruta a cargo de obtener datos de otra API y vuelva a formatearlos.

@martpie Es posible que desee consultar este comentario: https://github.com/zeit/next.js/issues/9524#issuecomment -589772756

¡La compatibilidad con la generación de sitios estáticos de próxima generación (SSG) se ha lanzado como estable en Next.js 9.3!

Esta versión también incluye soporte para "Modo de vista previa", o la capacidad de omitir la página renderizada previamente estáticamente y renderizar la página bajo demanda para usuarios autorizados .

Puede leer más sobre esto en nuestra publicación de blog . Si eres más práctico, ¡ve directamente a nuestros documentos !

¡ Publique cualquier pregunta en la

¡Esto es genial! ¡Gracias por el arduo trabajo!

Esta nueva característica no parece funcionar con saga y redux ahora

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

formula349 picture formula349  ·  3Comentarios

pie6k picture pie6k  ·  3Comentarios

wagerfield picture wagerfield  ·  3Comentarios

YarivGilad picture YarivGilad  ·  3Comentarios

jesselee34 picture jesselee34  ·  3Comentarios