Next.js: Ruta personalizada `post /` id` parpadeando 404 antes de finalmente renderizar la página.

Creado en 22 ago. 2017  ·  47Comentarios  ·  Fuente: vercel/next.js

Actualmente estoy experimentando un problema con mis rutas post/:id donde a continuación parpadea la página 404 antes de renderizar con éxito mi componente. Al principio, pensé que se trataba de un problema relacionado con la reducción, ya que mis páginas post/id están verificando el estado de la aplicación en filter cualquiera que sea el componente que debería mostrarse usando enrutamiento superficial.

Después de discutir esto en el canal de holgura, agregué otra llamada a la API que recuperaría cada publicación del blog, pero rápidamente descubrí que todavía encontraba el mismo problema. Sé que esto le ha sucedido al menos a otro desarrollador, así que me pregunto si alguien puede indicarme la dirección correcta. Estoy tratando de terminar esta carpeta personal con la que construí a continuación.

A continuación, puede ver exactamente lo que está sucediendo. Todo parece A1, excepto el 404 que parpadea cada vez que se procesa una publicación específica.

next.js blog post err

Los beneficios que obtuve son tremendos, sin embargo, ha habido algunos problemas menores como este que me han dejado un poco desconcertado 🤔. De todos modos, avíseme si puedo proporcionar información adicional. Gracias 😄

Comentario más útil

Entonces, para responder a esta de una vez por todas:

href => ruta dentro del directorio pages + la cadena de consulta
as => representado en la barra de URL del navegador

Ejemplo:

Tienes una URL llamada /products/:id

  1. Creaste pages/product.js
export default class extends React.Component {
  static async getInitialProps({query}) {
    console.log('SLUG', query.slug)
    return {}
  }
  render() {
    return <h1>The product page</h1>
  }
}
  1. Agrega la ruta a Express o cualquier otro servidor, esto es solo para SSR. Lo que esto hará es enrutar la URL /products/:id a pages/product.js y proporcionar id como parte de query en getInitialProps:
server.get("/products/:slug", (req, res) => {
  return app.render(req, res, "/product", { slug: req.params.slug })
})
  1. Para el enrutamiento del lado del cliente, usa next/link así:
<Link href="/product?slug=something" as="/products/something"> 

La razón por la que debe proporcionar explícitamente href y as es que Next.js no tiene conocimiento de ninguna otra página en el lado del cliente. No enviamos un manifiesto de todas las páginas al lado del cliente y las rutas posteriores se cargan de forma diferida, lo cual es escalable.

Hay un paquete comunitario que se abstrae proporcionando href y as enviando un manifiesto predefinido de todas las rutas, tenga en cuenta que recomendamos no enviar un manifiesto completo de todas las rutas posibles ya que no hace esto es más escalable

https://github.com/fridays/next-routes

Además, tenga en cuenta que renderizar 404 ya no es el comportamiento predeterminado de Next.js. En su lugar, recargamos la página para la función Zonas.

Todos 47 comentarios

Mismo problema +1

¿Cómo está procesando el componente Enlace a esa URL? ¿Está usando <Link href="/post/1"> o <Link href="/post?id=1" as="/post/1"> ?

Actualmente, estoy usando <Link prefetch href={ /blog/${x.id} } /> . Probé <Link prefetch href={ /blog/${x.id} } as={ /blog/${x.id} } /> en el pasado y simplemente lo conecté de nuevo. Sigo teniendo el mismo problema.

Sus href y as props no deberían ser los mismos, href es la URL real, si tiene pages/blog.js y recibe la identificación como una consulta, entonces href debería ser /blog?id=${x.id} y as es su bonita URL personalizada en este caso /blog/${x.id} .

@sergiodxa Acabo de poner este código en su lugar.

<Link href={`/blog?id=${x.id}`} as={`blog/${x.id}`}>
    <a>Read Post</a>
 </Link>

Ahora vuelve a renderizar la página /blog en cada clic mientras agrega id a la URL.

url error gif

@tgrecojs Espero que este fragmento de código ayude

    const href = `/journal?home=${this.state.article.path[0]}&articlePath=${this.state.article.path[1]}&file=${this.state.article.path[2]}`
    const as = `/journal/${this.state.article.path[0]}/${this.state.article.path[1]}/${this.state.article.path[2]}`

Se renderizaría como https://www.someURL.com/journal/articlePath/morePath/evenMorePath

Entiendo cómo funciona el camino @ugiacoman, ese no es mi problema. Si puede ver en mi informe inicial, estoy navegando con éxito a cada publicación del blog, sin embargo, el problema es ese extraño error 404 .

@tgrecojs Hice un repositorio de ejemplo https://github.com/sergiodxa/next-custom-query (implementado: https://next-custom-query.now.sh/blog), allí puedes ver cómo usar el URL personalizadas sin recargar y un 404 usando el componente next/link como se describe arriba.

@sergiodxa ¡

GIF eliminado

Ahora bien, este problema es una reproducción ligeramente diferente de este problema de lo que se muestra en mi primer comentario. Cuando me encontré con este problema por primera vez, pensé que era porque estaba usando redux y que el estado de la aplicación no se trasladaba a las páginas post/id . Esto me llevó a integrar una nueva llamada a la API para cada publicación, al igual que lo hice en la aplicación que ha creado, sin embargo, descubrí que tenía el mismo problema.

Estaba teniendo problemas para bifurcar su repositorio 😬, así que puede encontrar mi código aquí -> https://github.com/tgrecojs/next-custom-query-async . ¡Déjame saber tus pensamientos! 😄

Parece que está obteniendo un 400, al bifurcar su proyecto, obtengo el mismo error con un mensaje de error de límites de uso. Probablemente es por eso que está recibiendo ese error.

Está bien. Investigaré un poco más mañana, pero quiero señalar que el video que publiqué al abrir el problema no realiza una solicitud de API en la ruta /blog/:id . En cambio, está filtrando las publicaciones de mi tienda redux que se recopilan en la transición de ruta /blog por lo que esa no podría ser la razón por la que llegué a este problema. Solo implementé la segunda llamada a la API (realizada dentro de blog/:id ) porque pensé que tenía algo que ver con mi tienda redux, pero me encontré recibiendo el mismo error, pero esa no es la implementación actual en mi código.

Tan pronto como me di cuenta de que arrojaba el mismo error, volví a usar solo una llamada a la API (Inside /blog ) y luego filtrando la publicación de blog necesaria por id.

@sergiodxa Puedo confirmar que no son límites de uso. Verá que id no siempre se pasa correctamente a la ruta /blog/:id ... He adjuntado el error 400 que estoy recibiendo. Verá que id no está definido y (en este caso) parece ser la razón por la que recibo el error.

Incluí otro video a continuación. ¿Alguna idea de por qué se está comportando de esta manera? No he cambiado las etiquetas <Link /> dentro de este repositorio y todavía tengo el problema 😬.

next-custom-query err

Nuevamente, quiero señalar que el video de arriba muestra mi reproducción del error dentro del repositorio de ejemplo que ha creado: https://github.com/sergiodxa/next-custom-query .

También obtengo 404 parpadeando sin rutas personalizadas. Solo un archivo llamado orders.js en pages/ con este código:

import { Component } from 'react';

class Orders extends Component {
  render() {
    return (
      <div>
        <h2>My Orders</h2>
      </div>
    )
  }
}

export default Orders;

Parece un tema bastante crítico 😅

Traté de replicarlo y es porque la barra al final de la URL, si vas a /orders no ves el 404 pero si vas a /orders/ entonces ves eso 404 parpadeando antes del contenido, esto ocurre tanto en el modo de desarrollo como en el de producción.

Ah, este es un problema conocido. https://github.com/zeit/next.js/issues/1189

Mi problema no surgió debido a una barra diagonal, así que tiene que haber algo más, ¿verdad?

Hice algunos cambios en mi código e implementé 2 versiones diferentes, una que usa prefetch y otra que no. Quiero señalar que ninguna aplicación ahora puede cargar con éxito una ruta post/:id .

Con Prefetch - https://tgrecojs-hltqztsjpx.now.sh/

Uno notó que cuando uso prefetch en el enlace, ahora arroja un Page Does Not Exist Error al representar los enlaces para cada publicación de blog. Puedes ver una captura de pantalla de mi consola a continuación.

screen shot 2017-08-26 at 1 06 25 pm

Sin Prefetch- https://tgrecojs-qzpspdjrin.now.sh/

Cuando no uso la captación previa, el error que se muestra arriba ya no existe pero no procesa la aplicación. Cuando publiqué este problema inicialmente, mi componente estaba inicializando mi blog para cada componente post/:id . Desde entonces, eliminé eso, desde ahora, las publicaciones individuales nunca se procesan.

Avíseme si puedo proporcionar más información que pueda ayudar a diagnosticar este problema. 🤔

@tgrecojs Tengo casi exactamente el mismo problema. prefetch no resolvió mi problema.

El comportamiento que obtengo es el siguiente:

  • El usuario hace clic en el enlace.
  • Aparece un error 404
  • La página se recarga (??)
  • Después de recargar, se muestra la página correcta

¡Espero que esto pueda ayudar a solucionar el problema!

Información adicional: Nodo v6.10.3 , Chrome Version 60.0.3112.90

EDITAR: Implementé la aplicación para que puedan probarla https://datahub.now.sh/ , es el enlace / @ [nombre de usuario] el que tiene este comportamiento

@ Theo- el href en el siguiente / enlace es user?id=1 , ¿puedes probar /user?id=1 lugar? Creo que el 404 se debe a que Next.js está tratando de llegar a /current/path/user?id=1 lugar de /user?id=1 , pero cuando la página se vuelve a cargar, funciona bien debido al renderizado del servidor.

@sergiodxa que lo hizo. ¡Gracias!

@tgrecojs Tuve el mismo comportamiento 404 parpadeante. En mi caso, tenía un enlace con una variable de entorno que no funcionó en el cliente, por lo tanto, el 404 pero en el servidor, funcionó. Resuelto con https://medium.com/the-tech-bench/next-js-environment-variables-d2f6ea1a1dca.

@andreaskeller hmmm ok, lo comprobaré. gracias esto !!! Actualmente, SOLO estoy usando mis variables .env cuando la aplicación está renderizada en el servidor. Tengo un componente de orden superior que usa dotenv para verificar si es CSR o SSR, si es SSR, envío la función necesaria para registrar las publicaciones del blog.

sí, ya tengo mis variables funcionando bien. Estoy representando esa ruta /blog usando un HOC que obtiene mi BLOGGER_API_KEY por lo que está funcionando en esos ejemplos .... mis páginas secundarias /post/:id s no usan ninguna variables env.

Voy a investigar un poco más, ¡ojalá pueda llegar al fondo!

Parece que la mayoría de los problemas aquí están solucionados. También trabajaré en este problema https://github.com/zeit/next.js/issues/1189

Estoy cerrando esto ahora. Pero si necesitamos hacer algo en el núcleo, avíseme.

@sergiodxa según nuestra conversación de anoche, he creado la aplicación lil barebones que muestra mi problema. ¡Avíseme si tiene alguna pregunta al respecto! ¡Estaría más que feliz de informarle de todo lo que está sucediendo con él! 😄

No está arreglado.

Tengo el mismo problema pero sin rutas personalizadas. Tengo /pages/pipeline.tsx y / pipeline url funciona bien mientras / pipeline / parpadea 404 y luego intenta cargar mi página sin llamar a "getInitialProps" llamado (¡ya que era 404 en el servidor!).

@ ex3ndr No estoy seguro de si esto solucionará el problema, pero tuve un problema similar y esto lo solucionó.
https://github.com/zeit/next.js#disabling -file-system-routing

Es probable que lo siguiente sea intentar sacar el sistema de archivos antes de que se alcance su ruta personalizada.

@moaxaca Lo resolví de la misma manera ya que necesitaba tener mi propio enrutamiento personalizado; acabo de deshabilitar el siguiente por completo.

También veo este problema. La solución de @moaxaca no funcionó para mí. Lo que hizo fue usar cualquier componente Link , pero en su lugar optar por usar el método pushRoute next-routes.

Ejemplo básico:

import { connect } from 'react-redux'
import { Router } from '../routes'

// ----

export default class Link extends React.Component {

  handleClick(evt, url) {
    evt.preventDefault()    
    Router.pushRoute(url)
  }

  render() {
    const { url, title } = this.props

    return (
      <a href={ url} onClick={ (evt) => this.handleClick(evt, url) }>{title}</a>
    )
  }

}

Esto parece resolverlo y no veo el error parpadeando. Pero se siente un poco rápido.

guardar problema

Tuve el mismo problema antes y pude resolverlo. Estoy usando una configuración de servidor exprés. Descubrí que la razón por la que la página 404 parpadea antes de cargarse en la página correcta es porque la barra de mi página no coincide con el nombre de mi componente.

Cuando tengo este código, el 404 parpadea:

server.get('/search', (req, res) => {
    const actualPage = '/search_results'
    const queryParams = { filters: req.query }
    app.render(req, res, actualPage, queryParams)
  })

Tenga en cuenta que los valores /search y mis actualPage son diferentes.

Los destellos 404 desaparecen cuando cambio el nombre de mi componente y los valores actualPage para que sean los mismos que los de mi página slug, que es search . Vea el código de trabajo a continuación:

server.get('/search', (req, res) => {
    const actualPage = '/search'
    const queryParams = { filters: req.query }
    app.render(req, res, actualPage, queryParams)
  })

Ahora ambos están usando /search .

Lo siento por mis chicos ingleses.

Puede ser una buena idea revisar su propiedad next.config.js useFileSystemPublicRoutes . Si es falso, eso significa que debe definir todos los controladores de ruta en server.js usted mismo.

Esto corrige el 404 parpadeante para mí:

Enlace

<Link href="/somepage?id=value" as="/somepage/value">

Lado del servidor

server.get("/somepage/:id", (req, res) => {
  return app.render(req, res, "/maps", { id: req.params.id })
})

Parámetro de acceso en la página

const { id } = this.props.url.query

Entonces, para responder a esta de una vez por todas:

href => ruta dentro del directorio pages + la cadena de consulta
as => representado en la barra de URL del navegador

Ejemplo:

Tienes una URL llamada /products/:id

  1. Creaste pages/product.js
export default class extends React.Component {
  static async getInitialProps({query}) {
    console.log('SLUG', query.slug)
    return {}
  }
  render() {
    return <h1>The product page</h1>
  }
}
  1. Agrega la ruta a Express o cualquier otro servidor, esto es solo para SSR. Lo que esto hará es enrutar la URL /products/:id a pages/product.js y proporcionar id como parte de query en getInitialProps:
server.get("/products/:slug", (req, res) => {
  return app.render(req, res, "/product", { slug: req.params.slug })
})
  1. Para el enrutamiento del lado del cliente, usa next/link así:
<Link href="/product?slug=something" as="/products/something"> 

La razón por la que debe proporcionar explícitamente href y as es que Next.js no tiene conocimiento de ninguna otra página en el lado del cliente. No enviamos un manifiesto de todas las páginas al lado del cliente y las rutas posteriores se cargan de forma diferida, lo cual es escalable.

Hay un paquete comunitario que se abstrae proporcionando href y as enviando un manifiesto predefinido de todas las rutas, tenga en cuenta que recomendamos no enviar un manifiesto completo de todas las rutas posibles ya que no hace esto es más escalable

https://github.com/fridays/next-routes

Además, tenga en cuenta que renderizar 404 ya no es el comportamiento predeterminado de Next.js. En su lugar, recargamos la página para la función Zonas.

Gracias Tim, explicación totalmente clara!

@timneutkens
Si el enlace href y as. Paso el valor diferente. ¿Cómo puedo obtener el href y el valor de as ?
Probé mi demo. Creo que req.params.slug será el as . Entonces, ¿cómo podría obtener el href ?

@timneutkens Me salvaste, no sé cuántas horas de búsqueda dolorosa para mi problema: D

¿Cómo está procesando el componente Enlace a esa URL? ¿Está usando <Link href="/post/1"> o <Link href="/post?id=1" as="/post/1"> ?

Deberías poner esto en doc. :alegría:

@sergiodxa

Entonces, para responder a esta de una vez por todas:

href => ruta dentro del directorio pages + la cadena de consulta
as => representado en la barra de URL del navegador

Ejemplo:

Tienes una URL llamada /products/:id

  1. Creaste pages/product.js
export default class extends React.Component {
  static async getInitialProps({query}) {
    console.log('SLUG', query.slug)
    return {}
  }
  render() {
    return <h1>The product page</h1>
  }
}
  1. Agrega la ruta a Express o cualquier otro servidor, esto es _sólo_ para SSR. Lo que esto hará es enrutar la URL /products/:id a pages/product.js y proporcionar id como parte de query en getInitialProps:
server.get("/products/:slug", (req, res) => {
  return app.render(req, res, "/product", { slug: req.params.slug })
})
  1. Para el enrutamiento del lado del cliente, usa next/link así:
<Link href="/product?slug=something" as="/products/something"> 

La razón por la que debe proporcionar explícitamente href y as es que Next.js no tiene conocimiento de ninguna otra página en el lado del cliente. No enviamos un manifiesto de todas las páginas al lado del cliente y las rutas posteriores se cargan de forma diferida, lo cual es escalable.

Hay un paquete comunitario que se abstrae proporcionando href y as enviando un manifiesto predefinido de todas las rutas, tenga en cuenta que recomendamos no enviar un manifiesto completo de todas las rutas posibles ya que no hace esto es más escalable

https://github.com/fridays/next-routes

Además, tenga en cuenta que renderizar 404 ya no es el comportamiento predeterminado de Next.js. En su lugar, recargamos la página para la función Zonas.

qué puedo hacer si solo tengo una matriz de encabezados de lista como:
[ home: '/home', about:'/about', post: 'post/:post_id?' ] .
A continuación, solo obtengo un as's , pero ¿qué tal href ? Gracias: D

¿Qué pasa si estás usando router.push() lugar de <Link> cómo puedes lograr los mismos resultados?

@justinmchase Acabo de tener el mismo problema. Consulte la documentación de Next Router si aún no lo ha hecho.

Puedes usarlo como Router.push(url, as, options) :

Router.push('/post/[pid]', '/post/abc')

@timneutkens Me gustaría alojar mi aplicación next.js en ZEIT.now pero eso no tiene una opción para ejecutar un servidor express. ¿Pierdo mis bonitas URL ahora y solo puedo hacer param=value&param=value o hay otra manera? El ejemplo que publicó Sergio no parece prometedor

Probé rutas dinámicas pero ahora mi aplicación de una sola página está rota y enlaces como:

<Link href={`/integration?slug=${slug}`} as={`/integration/${slug}`}>

ahora provoca una recarga de página completa porque http: // localhost : 8080 / _next / static / development / pages / integration.js devuelve un 404 no encontrado.

@timneutkens Me gustaría alojar mi aplicación next.js en ZEIT.now pero eso no tiene una opción para ejecutar un servidor express. ¿Pierdo mis bonitas URL ahora y solo puedo hacer param=value&param=value o hay otra manera? El ejemplo que publicó Sergio no parece prometedor

No necesita un servidor personalizado para rutas dinámicas, consulte https://nextjs.org/docs/routing/dynamic-routes

@timneutkens Gracias por su rápida respuesta, probé rutas dinámicas pero romperé la aplicación de una sola página (ver actualización). Ejecutando localmente con next en mi script package.json en modo dev.

Lo resolvió teniendo un pages/integration/index.js con el código y un pages/integration/[slug].js con:

import ProductDetailPage from './index'
export default ProductDetailPage

La forma correcta de hacer lo que describió es crear pages/integration/[slug].js

Y vincularlo de esta manera:

<Link href={`/integration/[slug]`} as={`/integration/${slug}`}>

Hola, ¿puedo preguntar por qué cuando llamo a este?

Router.push( '/about?id=1234','/about')

la identificación no se puede recuperar, y la página que estoy usando es [... index] .js, que es una página multi dinámica que captura todas las páginas, pero si me dirijo a otra página que no es dinámica, puede funcionar correctamente, ejemplo car.js empujar a vehicle.js ..
¿Existe una mejor manera de empujar a mi página de captura dinámica y luego enmascarar la identificación y aún poder recuperarla ...?

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