UNPKG

3.67 kBJavaScriptView Raw
1import React from "react"
2import { Router, Location, BaseContext } from "@reach/router"
3import { ScrollContext } from "gatsby-react-router-scroll"
4
5import {
6 shouldUpdateScroll,
7 init as navigationInit,
8 RouteUpdates,
9} from "./navigation"
10import { apiRunner } from "./api-runner-browser"
11import loader from "./loader"
12import { PageQueryStore, StaticQueryStore } from "./query-result-store"
13import EnsureResources from "./ensure-resources"
14
15import { reportError, clearError } from "./error-overlay-handler"
16
17if (window.__webpack_hot_middleware_reporter__ !== undefined) {
18 const overlayErrorID = `webpack`
19 // Report build errors
20 window.__webpack_hot_middleware_reporter__.useCustomOverlay({
21 showProblems(type, obj) {
22 if (type !== `errors`) {
23 clearError(overlayErrorID)
24 return
25 }
26 reportError(overlayErrorID, obj[0])
27 },
28 clear() {
29 clearError(overlayErrorID)
30 },
31 })
32}
33
34navigationInit()
35
36// In gatsby v2 if Router is used in page using matchPaths
37// paths need to contain full path.
38// For example:
39// - page have `/app/*` matchPath
40// - inside template user needs to use `/app/xyz` as path
41// Resetting `basepath`/`baseuri` keeps current behaviour
42// to not introduce breaking change.
43// Remove this in v3
44const RouteHandler = props => (
45 <BaseContext.Provider
46 value={{
47 baseuri: `/`,
48 basepath: `/`,
49 }}
50 >
51 <PageQueryStore {...props} />
52 </BaseContext.Provider>
53)
54
55class LocationHandler extends React.Component {
56 render() {
57 const { location } = this.props
58
59 if (!loader.isPageNotFound(location.pathname)) {
60 return (
61 <EnsureResources location={location}>
62 {locationAndPageResources => (
63 <RouteUpdates location={location}>
64 <ScrollContext
65 location={location}
66 shouldUpdateScroll={shouldUpdateScroll}
67 >
68 <Router
69 basepath={__BASE_PATH__}
70 location={location}
71 id="gatsby-focus-wrapper"
72 >
73 <RouteHandler
74 path={encodeURI(
75 locationAndPageResources.pageResources.page.matchPath ||
76 locationAndPageResources.pageResources.page.path
77 )}
78 {...this.props}
79 {...locationAndPageResources}
80 />
81 </Router>
82 </ScrollContext>
83 </RouteUpdates>
84 )}
85 </EnsureResources>
86 )
87 }
88
89 const dev404PageResources = loader.loadPageSync(`/dev-404-page`)
90 const real404PageResources = loader.loadPageSync(`/404.html`)
91 let custom404
92 if (real404PageResources) {
93 custom404 = (
94 <PageQueryStore {...this.props} pageResources={real404PageResources} />
95 )
96 }
97
98 return (
99 <RouteUpdates location={location}>
100 <Router
101 basepath={__BASE_PATH__}
102 location={location}
103 id="gatsby-focus-wrapper"
104 >
105 <RouteHandler
106 path={location.pathname}
107 location={location}
108 pageResources={dev404PageResources}
109 custom404={custom404}
110 />
111 </Router>
112 </RouteUpdates>
113 )
114 }
115}
116
117const Root = () => (
118 <Location>
119 {locationContext => <LocationHandler {...locationContext} />}
120 </Location>
121)
122
123// Let site, plugins wrap the site e.g. for Redux.
124const WrappedRoot = apiRunner(
125 `wrapRootElement`,
126 { element: <Root /> },
127 <Root />,
128 ({ result, plugin }) => {
129 return { element: result }
130 }
131).pop()
132
133export default () => <StaticQueryStore>{WrappedRoot}</StaticQueryStore>
134
\No newline at end of file