Gatsby: Client-seitiges Routing deaktivieren?

Erstellt am 2. März 2018  ·  69Kommentare  ·  Quelle: gatsbyjs/gatsby

Beschreibung

Ich habe einen Anwendungsfall, in dem der Server einige benutzerdefinierte Routen definiert. Wenn der Browser diese Routen lädt, wird der erwartete Inhalt für einen kurzen Moment angezeigt, bis das clientseitige Routing die Seite übernimmt und durch die 404 ersetzt, da die URL im Browser nicht erkannt wird.

Mein erster Gedanke war, dass vielleicht das matchPath hier verwendet werden könnte, aber ich werde nicht unbedingt die URL-Muster kennen, die diese Seiten rendern würden, und es kann einige Überschneidungen geben, was die URL ist und welche Seite ist ist zurückgekommen.

Ich vermute, dass es mit einem Haken in der Find-Seite möglich sein könnte, aber ich bin mir nicht sicher, wie das aussehen würde.

Umgebung

Gatsby-Version: 1.9.221
Node.js Version: 8.9.1
Betriebssystem: macOS

Tatsächliche Ergebnis

Nachdem der Browser geladen wurde, wird die erwartete Seite kurz angezeigt, bis das Javascript geladen wird, festgestellt wird, dass die URL unbekannt ist, und die 404-Seite gerendert wird.

Erwartetes Verhalten

Die vom Server gerenderte Seite sollte unter der benutzerdefinierten URL verfügbar sein und beim Laden des Clients nicht durch die 404-Seite ersetzt werden.

Schritte zum Reproduzieren

1. git clone https://github.com/TuckerWhitehouse/gatsby-client-routing-issue

2. npm install

3. npm run build

4. npm start

5. open http://localhost:3000

awaiting author response question or discussion

Hilfreichster Kommentar

Basierend darauf, wie aktiv dieser Thread weiterhin ist, scheint es eine nicht triviale Anzahl von Benutzern zu geben, die dieses Verhalten wünschen.

Um meinen Anwendungsfall schnell zu wiederholen: Ich möchte ( tat! ) Gatsby als statischen _Seitengenerator verwenden - im Gegensatz zu einem statischen _Site_Generator - und weil die Gatsby- "Seite" in eine enthaltene Seite eingefügt wird, deren URL nicht mehr vorhanden ist Meine Kontrolle und Änderungen vorbehalten. Ich möchte nicht, dass die Gatsby-Anwendung mit der URL in Konflikt gerät. Gatsby unterstützt diesen Anwendungsfall sofort und ist sehr angenehm zu verwenden, macht jedoch einige Annahmen - wiederum aufgrund seines statischen Standard-Anwendungsfalls für die Site -, die dazu führen, dass Hacks wie die genannten erforderlich sind über.

Gibt es also Hoffnung, dass die Möglichkeit, das clientseitige Routing zu deaktivieren, zu einer Konfigurationsoption der obersten Ebene wird? Ich würde gerne eine PR einreichen, möchte aber keine Zeit darauf verwenden, wenn keine Chance besteht, dass sie akzeptiert wird.

Alle 69 Kommentare

Warum wissen Sie nicht, welche Pfade der Server rendert?

Es ist weniger so, dass ich die Pfade nicht kenne (ich kann einen regulären Ausdruck schreiben, der zu ihnen passt), als vielmehr die Überlappung. Das eigentliche Setup befindet sich hinter einem Apache-Server, der Proxys für eine Reihe verschiedener Apps, einschließlich der Gatsby-Site, umkehrt. Wenn eine dieser Apps nicht mehr verfügbar ist oder ein interner Serverfehler zurückgegeben wird, wird eine benutzerdefinierte Fehlerseite zurückgegeben, die Teil der gatsby-Site ist.

Wenn also app1 nicht verfügbar ist oder sich schlecht verhält, geben Anfragen an / app1 zu jedem Zeitpunkt den Inhalt von /error/unavailable.html oder /error/internal.html zurück, und dies gilt auch für app2 und so weiter .

Bei Verwendung eines matchPath wie /^(app1|app2)/.*/ funktioniert auf beiden nicht verfügbaren internen Fehlerseiten nicht, da findPage (basierend auf der URL) nicht weiß, welche Seite ich tatsächlich beabsichtige um den Benutzer zu zeigen.

Ich konnte mit einer globalen Variablen etwas zum Laufen bringen und ___history und ___loader in onClientEntry "patchen". Es ist sehr zerbrechlich, weil es von Gatsby abhängt, diese Globalen freizulegen - nicht sicher, ob es eine Möglichkeit gibt, dies zu verallgemeinern und zu Gatsby hinzuzufügen.

// gatsby-browser.js
exports.onClientEntry = () => {
  // Check for a custom pathname
  const pathname = global.___pathname
  if (!pathname) return

  // Override the history location
  const history = global.___history
  history.location.pathname = pathname

  // Patch the resource loader
  const loader = global.___loader
  const { getResourcesForPathname } = loader

  loader.getResourcesForPathname = (path, ...args) => {
    return getResourcesForPathname(path === location.pathname ? pathname : path, ...args)
  }
}
// src/pages/page1.js
import React from "react"
import Helmet from 'react-helmet'

export default () => (
  <div>
    <Helmet>
      <script>{`window.___pathname = '/page1'`}</script>
    </Helmet>
    <div>Page 1!</div>
  </div>
)

Ich stimme auch zu, dass es eine Build-Option geben sollte, um diese Funktion zu deaktivieren. Wir haben auch ein unkonventionelles Setup und möchten diese Funktion vorübergehend deaktivieren, während wir unsere Migration zu einer vollständigen Gatsby-Site beenden.

Eine einfache Flagge zur Erstellungszeit wäre perfekt.

wie wäre es mit diesem? eine Lösung dafür?

Am Ende haben wir die Datei pages.json so geändert, dass sie dem von uns benötigten Pfad entspricht. Wir nennen addPagesArray mit dem korrigierten Pfadnamen.

Ich verstehe immer noch nicht, warum dies einen Fehler auslöst? Die Seite wird gut geladen und funktioniert. Dies sollte höchstens eine Warnung sein, wenn es nicht mit dem Pfad übereinstimmt.

Davon abgesehen weiß ich nicht, ob es eine elegantere Möglichkeit gibt, die pages.json durch einen Konfigurations- oder Laufzeitcode zu ändern.

Ich möchte dieses Problem lösen.

Bei einem Projekt, an dem ich arbeite, tritt ein ähnliches Problem auf. Wir bauen einen Zielseitengenerator, der einseitige Gatsby-Apps erstellt. Dieses Problem tritt auf, wenn wir versuchen, eine Zielseite außerhalb ihrer Domain bereitzustellen.

So haben wir zum Beispiel unsere Haupt-Gatsby-App www.example.com . Wir haben einen Service, der die Gatsby-Zielseiten für www.example.com/trial . Eine Zielseiten-URL würde also wie folgt aussehen: www.example.com/trail/ad-123 Die Seite wird zunächst einwandfrei geladen, bis alle JS geladen sind und der Router die Kontrolle übernimmt. Die Zielseite zeigt den Pfad an und weiß nicht, wo er sich befindet. Daher versucht sie, den Pfad zu ändern, um die Seite im Stammverzeichnis zu platzieren. Sie sieht folgendermaßen aus: www.example.com/ad-123 , was zu einer 404-Umleitung führt.

Gibt es Pläne, eine konfigurierbare Option hinzuzufügen, um dies zu beheben? Wäre das Gatsby-Team offen für PR?

@ alex-greco-harrys mir Es scheint , dass ein Pfadpräfix ist , was Sie in diesem Szenario verwenden möchten.

Ich musste auch das clientseitige Routing deaktivieren, um Google Adsense auf meiner Website ordnungsgemäß auszuführen.

Automatische Google Adsense-Anzeigen erkennen kein clientseitiges Routing und die Anzeigen werden nicht aktualisiert, wenn Routen aktualisiert werden.

Kann ich das clientseitige Routing trotzdem deaktivieren?

In solchen Fällen können Sie a Tags anstelle von gatsby-link

Ich konnte mit einer globalen Variablen etwas zum Laufen bringen und ___history und ___loader in onClientEntry "patchen". Es ist sehr zerbrechlich, weil es von Gatsby abhängt, diese Globalen freizulegen - nicht sicher, ob es eine Möglichkeit gibt, dies zu verallgemeinern und zu Gatsby hinzuzufügen.

// gatsby-browser.js
exports.onClientEntry = () => {
  // Check for a custom pathname
  const pathname = global.___pathname
  if (!pathname) return

  // Override the history location
  const history = global.___history
  history.location.pathname = pathname

  // Patch the resource loader
  const loader = global.___loader
  const { getResourcesForPathname } = loader

  loader.getResourcesForPathname = (path, ...args) => {
    return getResourcesForPathname(path === location.pathname ? pathname : path, ...args)
  }
}
// src/pages/page1.js
import React from "react"
import Helmet from 'react-helmet'

export default () => (
  <div>
    <Helmet>
      <script>{`window.___pathname = '/page1'`}</script>
    </Helmet>
    <div>Page 1!</div>
  </div>
)

@TuckerWhitehouse Woher bekommst du ___history , ___loader ? Wenn ich versuche, Ihr Beispiel zu replizieren, sind diese beiden Eigenschaften von global undfined .

@ alex-greco-harrys mir Es scheint , dass ein Pfadpräfix ist , was Sie in diesem Szenario verwenden möchten.

@ jgierer12 Das hilft, das erste Stück meines Problems zu lösen. Das zweite Stück ist, dass der endgültige Pfad unbekannt ist, bis die Seite gerendert wird. Wir haben einen Lernservice, der eine Sammlung statischer Seiten auf der Grundlage der Conversion-Raten bereitstellt. Auf einem Pfad example.com/go/ könnten wir also 1 einer Sammlung von Seiten bedienen. Wir würden die Seite also nicht auf einem Pfad wie example.com/go/first-page oder example.com/go/second-page . Diese beiden würden auf example.com/go/page Pfad serviert.

Im Wesentlichen versuche ich, eine Gatsby-Seite auf einem beliebigen Pfad bereitzustellen.

@ alex-greco-harrys diese globals wurden von gatsby v1 ausgesetzt. Mit dem Upgrade auf Version 2 weiß ich, dass der zugrunde liegende Router von React-Router auf Reach-Router umgestellt wurde. Ich vermute also, dass diese globalen Router betroffen waren.

Ich hoffe auch, Gatsby zum Erstellen einer Einzelseitenanwendung verwenden zu können, und möchte das Routing vollständig deaktivieren. Kennt jemand eine Problemumgehung (a la

AKTUALISIEREN:
Obwohl ich keine Lösung finden konnte, die das clientseitige Routing deaktivieren würde, konnte ich die Umleitung verhindern, auf die @ alex-greco-harrys und andere verweisen, indem ich Folgendes festlegte:

window.page = window.page || {};
window.page.path = window.location.pathname;

in gatsby-browser.js, die diese bedingte Prüfung in Production-App.js kurzschließen. Diese bedingte Umleitung versucht, "den kanonischen Pfad an den tatsächlichen Pfad anzupassen" und führt zu dem (IMO) unerwarteten Verhalten, auf das oben verwiesen wurde.

Ich brauche das auch.

Ich verwende derzeit von Gatsby generierten Code für ein anderes Projekt und verwende ihn auf mehreren Seiten. Ich benutze Gatsby, da es statischen Code generiert. Daher habe ich pathPrefix , um alles unter einem bestimmten Pfad zu generieren und zu bedienen. Auf diese Weise wird dort alles angefordert und dann als Fragment einer Seite gerendert. Ich erhalte jedoch ständig unerwünschte Weiterleitungen zu pathPrefix da diese in den Skripten enthalten sind. Ich muss die Bedingung, die @ethagnawl bei jedem Build erwähnt hat, manuell entfernen. Ich habe gerade seine Lösung ausprobiert, aber es hat bei mir nicht funktioniert.

Ich hoffe auch, Gatsby zum Erstellen einer Einzelseitenanwendung verwenden zu können, und möchte das Routing vollständig deaktivieren. Kennt jemand eine Problemumgehung (a la

AKTUALISIEREN:
Obwohl ich keine Lösung finden konnte, die das clientseitige Routing deaktivieren würde, konnte ich die Umleitung verhindern, auf die @ alex-greco-harrys und andere verweisen, indem ich Folgendes festlegte:

window.page = window.page || {};
window.page.path = window.location.pathname;

in gatsby-browser.js, die diese bedingte Prüfung in Production-App.js kurzschließen. Diese bedingte Umleitung versucht, "den kanonischen Pfad an den tatsächlichen Pfad anzupassen" und führt zu dem (IMO) unerwarteten Verhalten, auf das oben verwiesen wurde.

@ethagnawl Ich habe eine hackige Lösung, um eine App mit nur einer Seite zu erstellen, die unter jeder URL bereitgestellt werden kann. Mit einer einzelnen Seite meine ich tatsächlich eine einzelne Seite ohne Routing.

Wenn Sie sich das folgende Gatsby-Beispiel ansehen: https://github.com/gatsbyjs/gatsby/tree/master/examples/client-only-paths .

Sie können diese Datei in Zeile 15 so bearbeiten, dass sie wie <Page path="/*" {...props} /> aussieht, und Zeile 16 löschen. Wenn Sie diese Anwendung erstellen, führt jeder Pfad dazu, dass die Page Ihnen definierten Page was Sie wollen. Wenn Sie diese Seite nun auf einem beliebigen Pfad hosten müssen, wird keine Umleitung angezeigt.

Ich konnte nicht herausfinden, wie diese Lösung mit mehreren Seiten in einer App funktionieren kann. Das Ziel meines Projekts war es, eine einzelne Gatsby-Seite (Marketing-Landingpage) unter einer beliebigen URL bereitzustellen.

Ich bin mir nicht sicher, ob dies in Ihrem Anwendungsfall hilfreich ist, aber vielleicht kann dies eine zukünftige Entdeckung befeuern!

Ich konnte dies erreichen, indem ich den Anweisungen zum Anpassen von html.js in den Dokumenten folgte und {this.props.postBodyComponents}

https://www.gatsbyjs.org/docs/custom-html/

Basierend darauf, wie aktiv dieser Thread weiterhin ist, scheint es eine nicht triviale Anzahl von Benutzern zu geben, die dieses Verhalten wünschen.

Um meinen Anwendungsfall schnell zu wiederholen: Ich möchte ( tat! ) Gatsby als statischen _Seitengenerator verwenden - im Gegensatz zu einem statischen _Site_Generator - und weil die Gatsby- "Seite" in eine enthaltene Seite eingefügt wird, deren URL nicht mehr vorhanden ist Meine Kontrolle und Änderungen vorbehalten. Ich möchte nicht, dass die Gatsby-Anwendung mit der URL in Konflikt gerät. Gatsby unterstützt diesen Anwendungsfall sofort und ist sehr angenehm zu verwenden, macht jedoch einige Annahmen - wiederum aufgrund seines statischen Standard-Anwendungsfalls für die Site -, die dazu führen, dass Hacks wie die genannten erforderlich sind über.

Gibt es also Hoffnung, dass die Möglichkeit, das clientseitige Routing zu deaktivieren, zu einer Konfigurationsoption der obersten Ebene wird? Ich würde gerne eine PR einreichen, möchte aber keine Zeit darauf verwenden, wenn keine Chance besteht, dass sie akzeptiert wird.

Dies scheint eine vernünftige Funktion zu sein, um @ethagnawl hinzuzufügen. Ich denke, es würde einen sehr langen und widerwärtigen Namen wie dangeouslySetInnerHTML brauchen, damit die Leute sich voll und ganz bewusst sind, was sie tun, da dies ein ganz besonderer Randfall ist.

Mein erster Durchgang bei einer PR, die sich mit diesem Problem befasst, finden Sie hier . Ich würde mich sehr über Feedback von Betreuern und / oder anderen Benutzern freuen, die auf dieses Problem gestoßen sind.

Vielen Dank, dass Sie aPR @ethagnawl

Können Sie mich noch einmal daran erinnern, warum das Folgende nicht funktioniert?

// Implement the Gatsby API “onCreatePage”. This is
// called after every page is created.
exports.onCreatePage = ({ page, actions }) => {
  const { createPage } = actions;
  page.matchPath = `${page.path}*`;
  createPage(page);
};

@wardpeet Ich bin sicher, das wird funktionieren und sieht ähnlich aus wie die oben erwähnte Lösung . Diese Arten von Lösungen sind jedoch schwer zu dokumentieren und möglicherweise fragil (siehe die von @TuckerWhitehouse angebotene

IMO, die Kodifizierung dieses Konzepts lohnt sich, da es wiederum die Dokumentation einfacher macht und dieses Flag auch verwendet werden kann, um zusätzliche Optimierungen durch Umgehen von / noop-ing / etc. Vorzunehmen. Funktionalität, die nicht relevant ist, wenn Gatsby auf diese Weise verwendet wird.

Darüber hinaus erfordert die Verwendung von matchPath dass die URL im Browser die Seite widerspiegelt, die Sie rendern möchten. Dies funktioniert jedoch nicht, wenn Sie eine Gatsby-Site an einem unbekannten Ort einfügen. (Mein ursprüngliches Problem bestand darin, Gatsby hinter einem Apache-Reverse-Proxy zu haben und die Routen nicht zu kennen, die zum Rendern einer bestimmten Seite führen würden.)

@ethagnawl Glaubst du, es wäre möglich, das Routing auf page.__disable_client_side_routing__ = true )? Dies würde wahrscheinlich auch das ursprüngliche Problem lösen, das ich hatte.

Glauben Sie, dass es möglich wäre, das Routing auf Seitenebene zu deaktivieren?

Ich verstehe nicht warum nicht? Wäre das zusätzlich zu oder anstelle meiner vorgeschlagenen Lösung? Wenn es das letztere ist, gibt es einen Vorteil, dies auf Seitenebene zu tun?

Ich habe dieses Repo eingerichtet :)
https://github.com/wardpeet/gatsby-plugin-static-site

unsicher, ob dies für Ihre Anwendungsfälle funktioniert.
Für jetzt müssen Sie tun

git clone https://github.com/wardpeet/gatsby-plugin-static-site
npm install
npm run build
npm link

cd "into your project"
npm link gatsby-plugin-static-site

füge gatsby-plugin-static-site zu deiner gatsby-config.js hinzu

Lassen Sie mich wissen, ob dies für Ihren Anwendungsfall in Ordnung ist. Ich habe nicht die Absicht, es tatsächlich zu unterstützen, daher bin ich froh, es zu übertragen: smile:

Ich habe das Repo aktualisiert, da in meiner Gitignore-Datei etwas nicht stimmte (danke @ m-allanson). Ich habe es auch unter meinem eigenen Namen bei npm veröffentlicht.

So kann die Installation durchgeführt werden

npm install --save @wardpeet/gatsby-plugin-static-site

und füge @wardpeet/gatsby-plugin-static-site zu gatsby-config.json hinzu

Wenn dies gut aussieht, kann ich einige Tests und Optionen hinzufügen, um dieses Verhalten für die Entwicklung zu deaktivieren.

Hiya!

Dieses Problem ist behoben. Gruselig leise. 👻

Wir haben viele Probleme, daher schließen wir Probleme derzeit nach 30 Tagen Inaktivität. Seit dem letzten Update hier sind mindestens 20 Tage vergangen.

Wenn wir dieses Problem verpasst haben oder wenn Sie es offen halten möchten, antworten Sie bitte hier. Sie können auch das Label "not stale" hinzufügen, um dieses Problem offen zu halten!

Vielen Dank, dass Sie Teil der Gatsby-Community sind! 💪💜

Ich möchte, dass dies offen bleibt, da es so aussieht, als würde es auf eine Überprüfung warten

Ich bin mir nicht sicher, ob es nicht abgestanden ist. Ich habe eine Korrektur vorgenommen und hoffe, Feedback dafür zu bekommen
https://github.com/gatsbyjs/gatsby/issues/4337#issuecomment -470075540

Wenn niemand antwortet, halte ich es für eine gute Idee, diese zu schließen, da sie wahrscheinlich gelöst ist.

@wardpeet Ist es mit diesem Plugin möglich, das clientseitige Routing bedingt zu deaktivieren?

@wardpeet IIRC, Ihr vorgeschlagener Fix ist der erste Schritt auf dem Weg, diese Funktion (möglicherweise) als Gatsby-Konfigurationsoption hinzuzufügen. Also, diese Art von macht es in Bezug auf dieses Problem und Gatsby aus der Band, aber ich könnte das Argument vorbringen, dass dieses Problem offen bleiben sollte, um dieses Gespräch fortzusetzen.

@wardpeet Das ursprüngliche Problem bestimmte Routen . @ethagnawl sprach den Anwendungsfall des Deaktivierens des Routings für eine gesamte Site an, was Ihrer Meinung nach Ihre Plugin-Adressen sind.

Ich muss das clientseitige Routing vorübergehend deaktivieren, während ich eine Site auf einem alten CMS nach Gatsby migriere. Ich mache es eine Seite nach der anderen, bevor ich den Schalter ganz auf Gatsby umlege.

Ich habe das @wardpeet- Plugin

@brianbento hast du eine reproduktion? Wenn Sie ein Problem auf dem Repo https://github.com/wardpeet/gatsby-plugin-static-site erstellen können, kann ich nachsehen, was fehlt

@wardpeet Ich werde sehen, ob ich etwas aufstehen kann. Das Hauptproblem ist, dass Ihr zuvor erwähnter "Fix" (https://github.com/gatsbyjs/gatsby/issues/4337#issuecomment-465497418) nicht funktioniert, wenn Sie pathPrefix verwenden. Es "korrigiert" die Adresse immer auf das, was erwartet wird.

@brianbento Hast du die oben erwähnte Lösung ausprobiert? Das hat bei zwei verschiedenen Projekten gut funktioniert.

@ethagnawl Ich bekomme immer noch die URL-Korrektur und dann verdoppelt sie das

Damit "/" wird "//."nachdem das kanonische nicht übereinstimmt.

Vielleicht implementiere ich es falsch. Haben Sie für Ihre Seiten das Pfadpräfix verwendet? Soll ich das statische Site-Plugin aktiv haben?

Haben Sie für Ihre Seiten das Pfadpräfix verwendet?

Ja. Ich habe diesen Zweig auch verwendet, um Remote-Assets zuzulassen. Es ist also möglich, dass dieser Zweig ein Verhalten eingeführt hat, durch das das Update für mich und nicht für Sie funktioniert hat.

Es ist jedoch wahrscheinlicher, dass die jüngsten Gatsby-Veröffentlichungen (ich habe nicht Schritt gehalten) meine "Lösung" gebrochen haben, da es zunächst ein Hack war.

@ethagnawl Super hilfreich! Vielen Dank! Ich weiß, dass @DSchau einige Plugins erstellt hat, um die AssetPrefix-Funktion zu testen. Ich versuche es mal!

Es scheint, dass die @wardpeet- Lösung nicht funktioniert, wenn Sie auch das __disable_client_side_routing__ , die den kanonischen Check deaktiviert, wäre super cool. Ich würde gerne daran arbeiten und eine PR einreichen, wenn diese für die Zusammenführung in Betracht gezogen wird. Gibt es Unterstützung für diese Idee oder passt sie Ihrer Meinung nach nicht in die Roadmap?

@xavivars Das würde mir gefallen und ich finde es sicher nützlich.

@xavivars Ich habe vor einiger Zeit einen Pass für dieses Feature genommen , der zugunsten der @wardpeet -Lösung geschlossen wurde. Wenn Sie überlegen, diesen Ansatz noch einmal zu überdenken, könnte es sich lohnen, einen Blick auf meinen Versuch zu werfen.

Danke @ethagnawl ! Ich habe mir Ihren Ansatz angesehen, und das war ziemlich genau das, was ich dachte.

Ich denke, die @wardpeet- Lösung deckt einen anderen Anwendungsfall ab: Die App verhält sich nicht wie ein SPA, da Links tatsächlich den Browser location.href ändern und dann auf der "Serverseite" navigieren. Aber ich konnte es für meinen Anwendungsfall nicht zum Laufen bringen, da die anfängliche Umleitung immer noch stattfindet: Meine anfängliche Hypothese ist, dass es eine Art Interaktion mit prefixPath , die diese Bedingung zu einer Bewertung von true

https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby/cache-dir/production-app.js#L65

Haben Sie es geschafft, dass es richtig funktioniert?

Ich könnte möglicherweise mehr am Plugin arbeiten, wenn mir jemand das eigentliche Problem erklären kann, da ich irgendwie vergessen habe, was ich beheben muss. Vielleicht kann das meiste davon durch die neu zusammengeführte AssetPrefix-Option gelöst werden?

Entschuldigung für das Unverständnis.

@xavivars

Haben Sie es geschafft, dass es richtig funktioniert?

Sowohl mein Hack als auch die eingereichte PR funktionierten für meinen Anwendungsfall einwandfrei: einzelne, statische Seitengenerierung ohne Weiterleitungen. Ich habe meine PR aufgegeben, weil das Gatsby-Team ein Plugin anstelle einer Konfigurationsoption auf App-Ebene zu bevorzugen schien.

Ich bin nie dazu gekommen , das Plugin von

@wardpeet : Das AssetPrefix sowohl Ihr Plugin (um die clientseitige "Navigation" beim Klicken im Grunde zu deaktivieren) als auch die von @ethagnawl vor einigen Monaten erwähnte

https://github.com/gatsbyjs/gatsby/issues/4337#issuecomment -453244611

Diese Problemumgehung ist erforderlich, um das "Navigations" -Ereignis zu deaktivieren, das onClientEntry . Wir haben das Hinzufügen eines Hooks dort und das Anwenden dieser Problemumgehung behoben (Erzwingen von page.path auf den tatsächlichen Pfad). Aber ich habe keine Ahnung, ob das irgendwelche Nebenwirkungen hat und wie lange es dauern wird, bis es nicht mehr funktioniert (ist nicht mehr als ein Hack).

Im Idealfall denke ich, dass dies eine Konfiguration auf App-Ebene sein sollte, da anscheinend viele Leute Gatsby als "statischen Seitengenerator" verwenden.

@xavivars Haben Sie einen Link, den Sie mit Ihrer Arbeit teilen können?

Nicht wirklich, aber das ist so ziemlich alles:

Fügen Sie das zuvor erwähnte statische Plugin und die Datei gastby-browser.js hinzu

exports.onClientEntry = () => {
    window.page = window.page || {};
    window.page.path = window.location.pathname;
}

Das Folgende funktioniert auch, obwohl es auf Gatsby-Interna basiert:

export function onInitialClientRender() {
  window.___navigate = (to, { replace }) => {
    if (replace) {
      window.location.replace(to);
    } else {
      window.location.assign(to);
    }
  };
}

Funktioniert die Verwendung von https://github.com/wardpeet/gatsby-plugin-static-site & assetPrefix?

Verknüpftes Problem, bei dem das Beispiel funktioniert hat. Sie sind sich nicht sicher, ob Sie dies tatsächlich benötigen.
https://github.com/wardpeet/gatsby-plugin-static-site/issues/1#issuecomment -494802726

Für mich funktionierte es mit allen drei Dingen: statische Site des Gatsby-Plugins + AssetPrefix + Deaktivieren der "Navigation" wie oben gezeigt

Es scheint, als ob es mir immer noch schwer fällt zu verstehen, was hier gebraucht wird. Ich konnte das Problem mit Gatsby-Plugin-Static-Site & AssetPrefix beheben.

@wardpeet Haben Sie einen Link zu einer Demo, die gatsby-plugin-static verwendet?

@ethagnawl Entschuldigung, Sie warten zu lassen.

Ich habe eine Demo gemacht:
https://github.com/wardpeet/gatsby-demos/tree/static-asset-prefix

Seite ist live:
https://zen-wright-33c2d8.netlify.com/

Wie erwartet (und von @TuckerWhitehouse und @ethagnawl erwartet) funktioniert eine fragile Lösung wie die unter https://github.com/gatsbyjs/gatsby/issues/4337#issuecomment -453244611 bereitgestellte aufgrund einer Änderung nicht mehr in Gatsby 2.9.2 aus mehreren Gründen:

Die erste, lösbare, ist diese Linie
window.page.path = window.location.pathname;
muss ersetzt werden durch
window.pagePath = window.location.pathname;
um die Änderung auf der URL-Client-Seite zu vermeiden.

Dies hat jedoch unerwünschte Nebenwirkungen: pagePath wird mit dem Pfad _wrong_ festgelegt, und page-data.json wird nicht mehr geladen (da es auf dem ursprünglichen Pfad der Seite basiert und nicht auf dem Pfad, auf dem es endgültig gerendert wird).

https://github.com/gatsbyjs/gatsby/commit/49fd769f695ccfa6e990e3eaae7c886f073db19b#diff -2d21ea42ec874a0988977e57b17251aa

Es scheint die einzige Möglichkeit zu sein, dies jetzt zum Laufen zu bringen, eine Variable wie __disable_client_side_routing__ oder zumindest __disable_client_side_canonical_redirect__ einzuführen, um diese Bedingung kurzzuschließen: https://github.com/gatsbyjs/ gatsby / blob / master / packages / gatsby / cache-dir / produktions-app.js # L69

@wardpeet :

Wir wollen diese Notluken lieber nicht im Kern aktivieren. Was ich im Grunde von dem Problem verstehe, ist Folgendes:

Ich habe eine Gatsby-Site und einen Pfad / my-special-path und auf meinem Server habe ich eine Route namens / etwas anderes. Wenn ich / etwas anderes in / gatsby / my-special-path umschreibe, funktioniert es nicht, weil versucht wird, die Seite in / my-special-path zu ändern?

Wenn ja, werde ich sehen, ob ich es in meinem Plugin beheben kann. Haben Sie vielleicht eine Live-Demo davon?

Ja, das ist genau das Problem. Ich werde versuchen, eine weitere PR zusammenzustellen (die als globale Konfigurationsvariable wie https://github.com/gatsbyjs/gatsby/pull/15173 nichts so Invasives hinzufügt).

Ich habe etwas, das akzeptabel sein könnte und das ich in ein paar Minuten als weitere PR veröffentlichen werde

@wardpeet Dies ist, was ich denke, würde benötigt, um zu Gatsby hinzuzufügen, damit Ihr Plugin erweitert werden könnte. Ich habe einige Beispiele und Dokumentationen zur PR hinzugefügt

https://github.com/gatsbyjs/gatsby/pull/15180

Nach einem Gespräch mit @DSchau in Discord scheinen die Hauptverantwortlichen der Meinung zu sein, dass eine Lösung wie # 15173 oder # 15180 nicht im Kern, sondern in einem Plugin leben sollte. Daher möchte ich andere Optionen untersuchen, um das Problem zu lösen.

Derzeit habe ich nur über eine globale Konfigurationsvariable (# 15173) die kanonische Umleitungsprüfung kurzgeschlossen oder die wahrgenommene gerenderte URL für gatsby (# 15180) geändert, sodass die kanonische Umleitungsprüfung nicht direkt davon abhängt window.location , aber für eine filterbare Variable.

IMHO besteht die Herausforderung darin, ein Plugin zu verwenden, um etwas zu erweitern / zu überschreiben, das derzeit nicht erweiterbar / überschreibbar zu sein scheint (direktes Verlassen auf window.location ohne die von irgendwo eingespeisten Werte macht es mir wirklich schwer). Es kann jedoch auch andere Möglichkeiten geben, dieses Verhalten zu implementieren, ohne den Code des Kerns zu ändern.

@xavivars Ich werde https://github.com/wardpeet/gatsby-plugin-static-site/pull/4 zusammenführen und einen Fix dafür veröffentlichen.

Eine Demo: (Seite 5 hat eine kanonische Weiterleitung)
https://static-asset-prefix--zen-wright-33c2d8.netlify.com/

Ich habe gerade @ wardpeet / gatsby-plugin-static-site Version 0.1.0 veröffentlicht. Dies sollte dieses Problem beheben. Fühlen Sie sich frei, erneut zu öffnen, wenn nicht alle Ihre Probleme behoben wurden.

Der beste Weg, um eine bessere Unterstützung für statische Websites zu erhalten, besteht darin, ein Problem im Plugin selbst zu erstellen. https://github.com/wardpeet/gatsby-plugin-static-site/issues/new

Hat dies jemand nach der Verwendung des obigen Plugins festgestellt?

Gibt es eine Problemumgehung für die aktuelle Version von GatsbyJS?

Ich habe es versucht:
https://github.com/wardpeet/gatsby-plugin-static-site

aber es funktioniert nicht bei mir. Ich habe hier ein Problem angesprochen:
https://github.com/wardpeet/gatsby-plugin-static-site/issues/13

Ich habe auch ein Beispiel-Repo erstellt, um das Umleitungsproblem zu reproduzieren:
https://github.com/isi-gach/gastby-static/tree/create-react-app

@ isi-gach Würde es Ihnen etwas ausmachen, Ihre Meinung zum Grundproblem zu äußern (was Sie erwarten, was Sie sehen, was Sie sehen möchten)? Einige von uns in diesem Thread haben es versucht, aber es könnte hilfreich sein, eine neue Sicht darauf zu bekommen.

hi @ethagnawl

Ich erwarte, dass sich die Browser-URL nicht ändert, aber ich sehe, dass sich die URL ändert. Im folgenden Video ändert sich die URL von /demo/index.html zu /public/
https://www.youtube.com/watch?v=SxYbaDidnkY

Dieses Video wurde mit dem von mir erstellten Beispiel-Repo aufgenommen:
https://github.com/isi-gach/gastby-static/tree/create-react-app

Ich versuche, die Umleitung mit @wardpeet/gatsby-plugin-static-site aber es scheint nicht zu funktionieren.

Hi @ isi-gach @ethagnawl ,

Es gibt einige Pull-Anfragen im @wardpeet- Plug-In, die das von Ihnen erwähnte Problem lösen sollen.

Während sie zusammengeführt werden, können Sie stattdessen meine Gabel verwenden

Hallo @xavivars
Ich habe das npm von Ihrer Gabelung ausprobiert und jetzt ändert sich die URL nicht, aber ich habe eine weiße Seite:
https://www.youtube.com/watch?v=uNzk9UYVCxk

Dieses Video wurde mit dem folgenden Beispiel-Repo aufgenommen, wobei das wardpeet durch Ihr Plugin ersetzt wurde:
https://github.com/isi-gach/gastby-static/tree/create-react-app

Wie deaktiviere ich das clientseitige Routing nur für eine einzelne Seite?

Sie können dies verwenden

exports.onPreBootstrap = ({ store }) => {
  const { program } = store.getState()
  const filePath = path.join(program.directory, '.cache', 'production-app.js')

  const code = fs.readFileSync(filePath, {
    encoding: `utf-8`,
  })

  const newCode = code.replace(
    `const { pagePath, location: browserLoc } = window`,
    `const { pagePath } = window
    let { location: browserLoc } = window

    if (window.parent.location !== browserLoc) {
      browserLoc = {
        pathname: pagePath
      }
    }
  `
  )

  fs.writeFileSync(filePath, newCode, `utf-8`)
}

Ich bin nicht sicher, ob es alle Anwendungsfälle abdeckt, die das Plugin abdeckt, aber es funktioniert gut für meinen Fall.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

kalinchernev picture kalinchernev  ·  3Kommentare

jimfilippou picture jimfilippou  ·  3Kommentare

timbrandin picture timbrandin  ·  3Kommentare

3CordGuy picture 3CordGuy  ·  3Kommentare

theduke picture theduke  ·  3Kommentare