From ce2867a8d5f896a1858801581b010821cfda2758 Mon Sep 17 00:00:00 2001 From: William Chargin Date: Wed, 15 Aug 2018 15:35:12 -0700 Subject: [PATCH] Use relative paths for router links (#672) Summary: As the next step for #643, this patch enables the app to be rendered at non-root gateways by incorporating the relative-path history implementation developed in #666. The app is not fully functional: our React components do not yet know how to resolve assets, and so fetches of resources like the repository will be against the wrong URLs. Test Plan: - Note that `yarn start` still works. - Run `./scripts/build_static_site.sh` to build the site into, say, `/tmp/gateway`. - Run a static web server from `/tmp/gateway/` and note that (a) the paths listed in the page source are relative, and (b) everything works as intended, with no console messages in either Chrome or Firefox. - Run a static web server from `/tmp/` and navigate to `/gateway/` in the browser. Note that the app loads properly, and that refreshes work (i.e., the `pushState` paths are real paths). Note that the repository registry cannot yet be loaded, and so PageRank cannot be run. wchargin-branch: relative-router --- src/app/App.js | 7 ++++--- src/app/index.js | 25 +++++++++++++++++++++---- src/app/server.js | 7 +++++-- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/app/App.js b/src/app/App.js index d746a45..788d512 100644 --- a/src/app/App.js +++ b/src/app/App.js @@ -1,16 +1,17 @@ // @flow import React from "react"; -import {Router, browserHistory} from "react-router"; +import {Router} from "react-router"; +import type {History /* actually `any` */} from "history"; import {createRoutes} from "./createRoutes"; import {resolveTitleFromPath} from "./routeData"; -export default class App extends React.Component<{}> { +export default class App extends React.Component<{|+history: History|}> { render() { return ( , root); + +let initialRoot: string = target.dataset.initialRoot; +if (initialRoot == null) { + console.error( + `Initial root unset (${initialRoot}): this should not happen! ` + + 'Falling back to ".".' + ); + initialRoot = "."; +} +const basename = normalize(`${window.location.pathname}/${initialRoot}/`); +const history = createRelativeHistory(createBrowserHistory(), basename); + +ReactDOM.hydrate(, target); // In Chrome, relative favicon URLs are recomputed at every pushState, // although other assets (like the `src` of an `img`) are not. We don't diff --git a/src/app/server.js b/src/app/server.js index 32e4e55..b556682 100644 --- a/src/app/server.js +++ b/src/app/server.js @@ -1,12 +1,14 @@ // @flow import {StyleSheetServer} from "aphrodite/no-important"; +import createMemoryHistory from "history/lib/createMemoryHistory"; import React from "react"; import ReactDOMServer from "react-dom/server"; import {match, RouterContext} from "react-router"; import Page from "./Page"; import {Assets, rootFromPath} from "./assets"; +import createRelativeHistory from "./createRelativeHistory"; import ExternalRedirect from "./ExternalRedirect"; import {createRoutes} from "./createRoutes"; import {resolveRouteFromPath, resolveTitleFromPath} from "./routeData"; @@ -19,6 +21,7 @@ export default function render( const path = locals.path; const root = rootFromPath(path); const assets = new Assets(root); + const history = createRelativeHistory(createMemoryHistory(path), "/"); { const route = resolveRouteFromPath(path); if (route && route.contents.type === "EXTERNAL_REDIRECT") { @@ -31,7 +34,7 @@ export default function render( function renderStandardRoute() { const bundlePath = locals.assets["main"]; const routes = createRoutes(); - match({routes, location: path}, (error, redirectLocation, renderProps) => { + match({history, routes}, (error, redirectLocation, renderProps) => { if (error) { callback(error); } else if (renderProps) { @@ -53,7 +56,7 @@ export default function render( -
${html}
+
${html}