Next.js: Benutzerdefinierte Route `post/`id` blinkt 404 vor dem endgültigen Rendern der Seite.

Erstellt am 22. Aug. 2017  ·  47Kommentare  ·  Quelle: vercel/next.js

Ich habe derzeit ein Problem mit meinen post/:id Routen, bei denen als nächstes die 404 Seite blinkt, bevor meine Komponente erfolgreich gerendert wird. Zuerst dachte ich, dies sei ein Redux-Problem, da meine post/id Seiten den App-Status auf filter überprüfen,

Nachdem ich dies im Slack-Channel besprochen hatte, fügte ich einen weiteren API-Aufruf hinzu, der jeden Blogbeitrag abrufen würde, stellte jedoch schnell fest, dass ich immer noch auf dasselbe Problem gestoßen bin. Ich weiß, dass dies bei mindestens einem anderen Entwickler passiert ist, also frage ich mich, ob mir jemand in die richtige Richtung weisen kann? Ich versuche, dieses persönliche Portfolio, mit dem ich als nächstes aufgebaut habe, fertigzustellen.

Unten können Sie genau sehen, was passiert. Alles sieht A1 aus, mit Ausnahme des 404, der blinkt, wenn ein bestimmter Beitrag gerendert wird.

next.js blog post err

Die Vorteile, die ich gewonnen habe, sind enorm, aber es gab einige kleinere Probleme wie diese, die mich ein wenig verwirrt haben 🤔 . Auf jeden Fall lassen Sie es mich wissen, wenn ich zusätzliche Informationen liefern kann. Danke 😄

Hilfreichster Kommentar

Um diese ein für alle Mal zu beantworten:

href => Pfad innerhalb des Verzeichnisses pages + der Abfragestring
as => gerendert in der Browser-URL-Leiste

Beispiel:

Sie haben eine URL namens /products/:id

  1. Du hast 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. Sie fügen die Route zu Express oder einem anderen Server hinzu, dies gilt nur für SSR. Dadurch wird die URL /products/:id an pages/product.js und id als Teil von query in getInitialProps bereitgestellt:
server.get("/products/:slug", (req, res) => {
  return app.render(req, res, "/product", { slug: req.params.slug })
})
  1. Für das clientseitige Routing verwenden Sie next/link wie folgt:
<Link href="/product?slug=something" as="/products/something"> 

Der Grund, warum Sie href und as explizit angeben müssen, ist, dass Next.js keine anderen Seiten auf der Clientseite kennt. Wir senden kein Manifest aller Seiten an die Clientseite und nachfolgende Routen werden verzögert geladen, was skalierbar ist.

Es gibt ein Community-Paket, das abstrahiert und href und as bereitstellt, indem ein vordefiniertes Manifest aller Routen gesendet wird ist skalierbarer

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

Beachten Sie außerdem, dass das Rendern von 404 nicht mehr das Standardverhalten von Next.js ist. Stattdessen laden wir die Seite für die Zonenfunktion neu.

Alle 47 Kommentare

Gleiches Problem +1

Wie rendern Sie die Link-Komponente zu dieser URL? Verwenden Sie <Link href="/post/1"> oder <Link href="/post?id=1" as="/post/1"> ?

Derzeit verwende ich <Link prefetch href={ /blog/${x.id} } /> . Ich habe in der Vergangenheit <Link prefetch href={ /blog/${x.id} } as={ /blog/${x.id} } /> ausprobiert und es einfach wieder angeschlossen. Habe immer noch das gleiche Problem.

Ihre href und as Requisiten sollten nicht gleich sein, href ist die echte URL, wenn Sie pages/blog.js und die ID als Abfrage erhalten dann href sollte /blog?id=${x.id} und as ist in diesem Fall Ihre hübsche benutzerdefinierte URL /blog/${x.id} .

@sergiodxa Ich habe gerade diesen Code

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

Jetzt wird die /blog Seite bei jedem Klick neu gerendert, während id zur URL hinzugefügt wird.

url error gif

@tgrecojs Hoffe, dieser

    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]}`

Würde als https://www.someURL.com/journal/articlePath/morePath/evenMorePath rendern

Ich verstehe, wie der Pfad funktioniert @ugiacoman , das ist nicht mein Problem. Wenn Sie in meinem ersten Bericht sehen können, navigiere ich erfolgreich zu jedem Blog-Post, aber das Problem ist dieser seltsame 404 Fehler.

@tgrecojs Ich habe ein Beispiel-Repo erstellt https://github.com/sergiodxa/next-custom-query (eingesetzt: https://next-custom-query.now.sh/blog), dort können Sie sehen, wie Sie das verwenden benutzerdefinierte URLs ohne Neuladen und eine 404 mit der next/link Komponente wie oben beschrieben.

@sergiodxa Das

Entfernte Gifs

Nun ist dieses Problem eine etwas andere Reproduktion dieses Problems als das, was in meinem ersten Kommentar gezeigt wird. Als ich zum ersten Mal auf dieses Problem stieß, dachte ich, es liege daran, dass ich Redux verwende und dass der Anwendungsstatus die post/id Seiten nicht überträgt. Dies führte mich dazu, für jeden Beitrag einen neuen API-Aufruf zu integrieren, genau wie ich ihn in die von Ihnen erstellte App integriert habe, aber ich habe immer noch festgestellt, dass ich das gleiche Problem hatte.

Ich hatte Probleme beim Forking Ihres Repo 😬, also finden Sie meinen Code hier -> https://github.com/tgrecojs/next-custom-query-async . Lass mich deine Gedanken wissen! 😄

Es sieht so aus, als ob Sie eine 400 erhalten. Wenn Sie Ihr Projekt verzweigen, erhalte ich denselben Fehler mit einer useLimits-Fehlermeldung. Das ist wahrscheinlich der Grund, warum Sie diesen Fehler erhalten.

Okay. Ich werde morgen etwas genauer nachforschen, aber ich möchte darauf hinweisen, dass das Video, das ich beim Öffnen des Problems gepostet habe, keine API-Anfrage auf der Route /blog/:id . Stattdessen filtert es die Posts aus meinem Redux Store, die auf dem /blog Routenübergang gesammelt werden, so dass dies nicht der Grund sein kann, warum ich auf dieses Problem gestoßen bin. Ich habe nur den 2. API-Aufruf implementiert (in blog/:id ), da ich dachte, es hätte etwas mit meinem Redux-Store zu tun, aber ich habe den gleichen Fehler erhalten, aber das ist nicht die aktuelle Implementierung in meinem Code.

Sobald mir klar wurde, dass es den gleichen Fehler gab, wechselte ich wieder dazu, nur einen API-Aufruf (Inside /blog ) zu verwenden und dann nach dem erforderlichen Blogbeitrag nach ID zu filtern.

@sergiodxa Ich kann bestätigen, dass es sich nicht um Nutzungsbeschränkungen handelt. Sie werden sehen, dass id nicht immer korrekt an die /blog/:id Route übergeben wird... Ich habe den 400 Fehler angehängt, den ich erhalte. Sie werden sehen, dass id definiert ist und (in diesem Fall) scheint es der Grund zu sein, warum ich den Fehler erhalte.

Ich habe unten ein weiteres Video eingefügt. Irgendwelche Gedanken, warum es sich so verhält? Ich habe die <Link /> Tags in diesem Repository nicht geändert, habe aber immer noch das Problem 😬 .

next-custom-query err

Auch hier möchte ich darauf hinweisen, dass das obige Video zeigt, wie ich den Fehler in dem von Ihnen erstellten Beispiel-Repository reproduziere - https://github.com/sergiodxa/next-custom-query .

Ich bekomme auch 404-Blinken ohne benutzerdefinierte Routen. Nur eine Datei namens orders.js in pages/ mit diesem Code:

import { Component } from 'react';

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

export default Orders;

Scheint ein ziemlich kritisches Thema zu sein 😅

Ich habe versucht, es zu replizieren, und das liegt daran, dass der nachgestellte Schrägstrich am Ende der URL, wenn Sie zu /orders Sie den 404 nicht sehen, aber wenn Sie zu /orders/ gehen, sehen Sie das 404 blinkt vor dem Inhalt, dies geschieht entweder im Entwicklungs- oder Produktionsmodus.

Ah das ist ein bekanntes Problem. https://github.com/zeit/next.js/issues/1189

Mein Problem ist nicht aufgrund eines nachgestellten Schrägstrichs aufgetreten, also muss es etwas anderes geben, oder?

Ich habe einige Änderungen an meinem Code vorgenommen und 2 verschiedene Versionen bereitgestellt, eine mit prefetch und eine ohne. Ich möchte darauf hinweisen, dass keine der Anwendungen jetzt erfolgreich eine post/:id Route laden kann.

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

Man bemerkte, dass, wenn ich prefetch im Link verwende, es jetzt ein Page Does Not Exist Error auslöst, wenn die Links für jeden Blogbeitrag gerendert werden. Unten seht ihr einen Screenshot meiner Konsole.

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

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

Wenn ich Prefetch nicht verwende, existiert der oben gezeigte Fehler nicht mehr, aber die Anwendung wird nicht gerendert. Als ich dieses Problem zum ersten Mal veröffentlicht habe, initialisierte meine Komponente meinen Blog für jede post/:id Komponente. Ich habe das inzwischen entfernt, da einzelne Posts jetzt nie rendern rendern im Glossar erklärt .

Lassen Sie es mich wissen, wenn ich weitere Informationen bereitstellen kann, die bei der Diagnose dieses Problems helfen können. 🤔

@tgrecojs Ich habe fast genau das gleiche Problem. prefetch hat mein Problem nicht gelöst.

Das Verhalten, das ich erhalte, ist folgendes:

  • Der Benutzer klickt auf den Link
  • Ein 404-Fehler wird angezeigt
  • Die Seite wird neu geladen (??)
  • Nach dem erneuten Laden wird die richtige Seite angezeigt

Ich hoffe, das kann helfen, das Problem zu beheben!

Zusätzliche Informationen: Knoten v6.10.3 , Chrome Version 60.0.3112.90

BEARBEITEN: Die App wurde bereitgestellt, damit Sie sie testen können https://datahub.now.sh/ , der Link /@[Benutzername] hat dieses Verhalten

@Theo- der href in diesem nächsten/link ist user?id=1 , kannst du es stattdessen mit /user?id=1 versuchen? Ich denke, der 404 liegt daran, dass Next.js versucht, zu /current/path/user?id=1 anstelle von /user?id=1 , aber wenn die Seite neu geladen wird, funktioniert es aufgrund des Server-Renderings gut.

@sergiodxa das hat es getan. Dankeschön!

@tgrecojs Ich hatte das gleiche blinkende 404-Verhalten. In meinem Fall hatte ich einen Link mit einer Umgebungsvariablen, die auf dem Client nicht funktionierte, daher die 404, aber auf dem Server funktionierte es. Gelöst mit https://medium.com/the-tech-bench/next-js-environment-variables-d2f6ea1a1dca.

@andreaskeller hmmm ok ich werde es

Ja, meine Variablen funktionieren bereits. Ich bin Rendering , dass meine /blog Strecke eine HOC verwenden , die mein bekommt BLOGGER_API_KEY , so dass es in diesen Beispielen arbeiten ist .... meine /post/:id s Kind Seiten nicht verwenden , jede env-Variablen.

Ich werde noch ein bisschen graben, hoffentlich komme ich der Sache auf den Grund!

Es scheint, als wären die meisten Probleme hier behoben. Ich werde auch an diesem Thema arbeiten https://github.com/zeit/next.js/issues/1189

Ich schließe das jetzt. Aber wenn wir etwas im Kern tun müssen, lassen Sie es mich wissen.

@sergiodxa gemäß unserem Gespräch

Es ist nicht fest.

Ich habe das gleiche Problem, aber ohne benutzerdefinierte Routen. Ich habe /pages/pipeline.tsx und /pipeline url funktioniert einwandfrei, während /pipeline/ 404 blinkt und dann versucht, meine Seite zu laden, ohne "getInitialProps" aufgerufen zu haben (da es 404 auf dem Server war!).

@ex3ndr Nicht sicher, ob das Problem dadurch
https://github.com/zeit/next.js#disabling -file-system-routing

Die Chancen stehen gut, dass als nächstes versucht wird, das Dateisystem abzurufen, bevor Ihre benutzerdefinierte Route erreicht wird.

@moaxaca Ich habe es auf die gleiche Weise gelöst, da ich mein eigenes benutzerdefiniertes Routing benötigt habe - ich habe gerade das nächste komplett deaktiviert.

Ich sehe dieses Problem auch. Die Lösung von @moaxaca hat bei mir nicht funktioniert. Stattdessen wurde eine beliebige Link Komponente verwendet, aber stattdessen die pushRoute Methode von next-routes verwendet.

Grundlegendes Beispiel:

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

}

Dies scheint es herauszufinden und ich sehe den Fehler nicht blinken. Aber es fühlt sich ein bisschen schnell an.

Problem speichern

Ich hatte das gleiche Problem schon einmal und konnte es lösen. Ich verwende ein Express-Server-Setup. Ich habe herausgefunden, dass der Grund, warum die 404-Seite blinkt, bevor die richtige Seite geladen wird, darin besteht, dass mein Seiten-Slug nicht mit meinem Komponentennamen übereinstimmt.

Wenn ich diesen Code habe, blinkt die 404:

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

Beachten Sie, dass die Werte für /search und meine actualPage unterschiedlich sind.

Die 404-Blitze verschwinden, wenn ich meine Komponente umbenenne und die actualPage Werte mit meinem Seiten-Slug übereinstimmen, der search . Siehe Arbeitscode unten:

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

Jetzt verwenden beide /search .

Sorry für meine Engländer.

es kann eine gute Idee sein, next.config.js useFileSystemPublicRoutes Eigenschaft zu überprüfen. Wenn es falsch ist, müssen Sie alle Routenhandler in server.js selbst definieren.

Dies behebt den blinkenden 404 für mich:

Verknüpfung

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

Serverseite

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

Zugriffsparameter auf Seite

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

Um diese ein für alle Mal zu beantworten:

href => Pfad innerhalb des Verzeichnisses pages + der Abfragestring
as => gerendert in der Browser-URL-Leiste

Beispiel:

Sie haben eine URL namens /products/:id

  1. Du hast 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. Sie fügen die Route zu Express oder einem anderen Server hinzu, dies gilt nur für SSR. Dadurch wird die URL /products/:id an pages/product.js und id als Teil von query in getInitialProps bereitgestellt:
server.get("/products/:slug", (req, res) => {
  return app.render(req, res, "/product", { slug: req.params.slug })
})
  1. Für das clientseitige Routing verwenden Sie next/link wie folgt:
<Link href="/product?slug=something" as="/products/something"> 

Der Grund, warum Sie href und as explizit angeben müssen, ist, dass Next.js keine anderen Seiten auf der Clientseite kennt. Wir senden kein Manifest aller Seiten an die Clientseite und nachfolgende Routen werden verzögert geladen, was skalierbar ist.

Es gibt ein Community-Paket, das abstrahiert und href und as bereitstellt, indem ein vordefiniertes Manifest aller Routen gesendet wird ist skalierbarer

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

Beachten Sie außerdem, dass das Rendern von 404 nicht mehr das Standardverhalten von Next.js ist. Stattdessen laden wir die Seite für die Zonenfunktion neu.

Danke Tim, total klare Erklärung!

@timneutkens
Wenn die href und as. Ich übergebe den anderen Wert. Wie könnte ich den href und den Wert von as ?
Ich teste mir Demo. Ich denke, req.params.slug wird den as haben. Wie könnte ich dann den href .

@timneutkens Du hast mich gerettet, ich weiß nicht, wie viele Stunden mühsamer Suche nach meinem Problem :D

Wie rendern Sie die Link-Komponente zu dieser URL? Verwenden Sie <Link href="/post/1"> oder <Link href="/post?id=1" as="/post/1"> ?

Das solltest du in doc eintragen. :Freude:

@sergiodxa

Um diese ein für alle Mal zu beantworten:

href => Pfad innerhalb des Verzeichnisses pages + der Abfragestring
as => gerendert in der Browser-URL-Leiste

Beispiel:

Sie haben eine URL namens /products/:id

  1. Du hast 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. Sie fügen die Route zu Express oder einem anderen Server hinzu, dies ist _nur_ für SSR. Dadurch wird die URL /products/:id an pages/product.js und id als Teil von query in getInitialProps bereitgestellt:
server.get("/products/:slug", (req, res) => {
  return app.render(req, res, "/product", { slug: req.params.slug })
})
  1. Für das clientseitige Routing verwenden Sie next/link wie folgt:
<Link href="/product?slug=something" as="/products/something"> 

Der Grund, warum Sie href und as explizit angeben müssen, ist, dass Next.js keine anderen Seiten auf der Clientseite kennt. Wir senden kein Manifest aller Seiten an die Clientseite und nachfolgende Routen werden verzögert geladen, was skalierbar ist.

Es gibt ein Community-Paket, das abstrahiert und href und as bereitstellt, indem ein vordefiniertes Manifest aller Routen gesendet wird ist skalierbarer

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

Beachten Sie außerdem, dass das Rendern von 404 nicht mehr das Standardverhalten von Next.js ist. Stattdessen laden wir die Seite für die Zonenfunktion neu.

Was kann ich tun, wenn ich nur ein Array von Listenheadern habe wie:
[ home: '/home', about:'/about', post: 'post/:post_id?' ] .
Als nächstes bekomme ich nur as's Wert, aber wie wäre es mit href ? Danke: D

Was ist, wenn Sie router.push() anstelle von <Link> wie können Sie die gleichen Ergebnisse erzielen?

@justinmchase Ich hatte gerade das gleiche Problem. Lesen Sie die Dokumentation zum nächsten Router , falls Sie dies noch nicht

Sie können es als Router.push(url, as, options) :

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

@timneutkens Ich möchte meine next.js-App auf ZEIT.now hosten, aber das hat keine Option, einen Express-Server zu betreiben. Verliere ich jetzt meine hübschen URLs und kann nur noch param=value&param=value oder gibt es einen anderen Weg? Das von Sergio gepostete Beispiel sieht nicht vielversprechend aus

Ich habe dynamische Routen ausprobiert

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

Verursachen Sie jetzt ein Neuladen der ganzen Seite, weil http://localhost :8080/_next/static/development/pages/integration.js eine 404 nicht gefunden zurückgibt.

@timneutkens Ich möchte meine next.js-App auf ZEIT.now hosten, aber das hat keine Option, einen Express-Server zu betreiben. Verliere ich jetzt meine hübschen URLs und kann nur noch param=value&param=value oder gibt es einen anderen Weg? Das von Sergio gepostete Beispiel sieht nicht vielversprechend aus

Sie benötigen keinen benutzerdefinierten Server für dynamische Routen, siehe https://nextjs.org/docs/routing/dynamic-routes

@timneutkens Vielen Dank für Ihre schnelle Antwort, ich habe dynamische Routen ausprobiert, aber die Einzelseitenanwendung wird next in meinem package.json-Skript im Entwicklungsmodus.

Gelöst, indem ein pages/integration/index.js mit dem Code und ein pages/integration/[slug].js mit:

import ProductDetailPage from './index'
export default ProductDetailPage

Der richtige Weg, um das zu tun, was Sie beschrieben haben, besteht darin, pages/integration/[slug].js zu erstellen

Und verlinke es auf diese Weise:

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

Hallo, darf ich fragen warum, wenn ich diesen anrufe?

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

Die ID kann nicht abgerufen werden, und die Seite, die ich verwende, ist [...index].js, eine multi-dynamische Catch-All-Seite, aber wenn ich zu einer anderen Seite leite, die nicht dynamisch ist, kann sie ordnungsgemäß funktionieren. Beispiel car.js push to vehicle.js..
Gibt es eine bessere Möglichkeit, zu meiner dynamischen Catch-All-Seite zu gelangen und dann die ID zu maskieren und sie trotzdem abzurufen?

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen