-
Notifications
You must be signed in to change notification settings - Fork 10.3k
/
Copy pathroot.js
147 lines (136 loc) · 4.47 KB
/
root.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import React from "react"
import { Router, Location, BaseContext } from "@gatsbyjs/reach-router"
import { ScrollContext } from "gatsby-react-router-scroll"
import { SlicesMapContext, SlicesContext } from "./slice/context"
import { shouldUpdateScroll, RouteUpdates } from "./navigation"
import { apiRunner } from "./api-runner-browser"
import loader from "./loader"
import {
PageQueryStore,
StaticQueryStore,
SliceDataStore,
} from "./query-result-store"
import EnsureResources from "./ensure-resources"
import FastRefreshOverlay from "./fast-refresh-overlay"
// In gatsby v2 if Router is used in page using matchPaths
// paths need to contain full path.
// For example:
// - page have `/app/*` matchPath
// - inside template user needs to use `/app/xyz` as path
// Resetting `basepath`/`baseuri` keeps current behaviour
// to not introduce breaking change.
// Remove this in v3
const RouteHandler = props => (
<BaseContext.Provider
value={{
baseuri: `/`,
basepath: `/`,
}}
>
<PageQueryStore {...props} />
</BaseContext.Provider>
)
class LocationHandler extends React.Component {
render() {
const { location } = this.props
const slicesContext = {
renderEnvironment: `browser`,
}
if (!loader.isPageNotFound(location.pathname + location.search)) {
return (
<EnsureResources location={location}>
{locationAndPageResources => (
<SlicesContext.Provider value={slicesContext}>
<SlicesMapContext.Provider
value={locationAndPageResources.pageResources.page.slicesMap}
>
<RouteUpdates location={location}>
<ScrollContext
location={location}
shouldUpdateScroll={shouldUpdateScroll}
>
<Router
basepath={__BASE_PATH__}
location={location}
id="gatsby-focus-wrapper"
>
<RouteHandler
path={encodeURI(
(
locationAndPageResources.pageResources.page
.matchPath ||
locationAndPageResources.pageResources.page.path
).split(`?`)[0]
)}
{...this.props}
{...locationAndPageResources}
/>
</Router>
</ScrollContext>
</RouteUpdates>
</SlicesMapContext.Provider>
</SlicesContext.Provider>
)}
</EnsureResources>
)
}
const dev404PageResources = loader.loadPageSync(`/dev-404-page`)
const real404PageResources = loader.loadPageSync(`/404.html`)
let custom404
if (real404PageResources) {
custom404 = (
<PageQueryStore {...this.props} pageResources={real404PageResources} />
)
}
return (
<EnsureResources location={location}>
{locationAndPageResources => (
<SlicesContext.Provider value={slicesContext}>
<SlicesMapContext.Provider
value={locationAndPageResources.pageResources.page.slicesMap}
>
<RouteUpdates location={location}>
<Router
basepath={__BASE_PATH__}
location={location}
id="gatsby-focus-wrapper"
>
<RouteHandler
path={location.pathname}
location={location}
pageResources={dev404PageResources}
custom404={custom404}
/>
</Router>
</RouteUpdates>
</SlicesMapContext.Provider>
</SlicesContext.Provider>
)}
</EnsureResources>
)
}
}
const Root = () => (
<Location>
{locationContext => <LocationHandler {...locationContext} />}
</Location>
)
// Let site, plugins wrap the site e.g. for Redux.
const rootWrappedWithWrapRootElement = apiRunner(
`wrapRootElement`,
{ element: <Root /> },
<Root />,
({ result, plugin }) => {
return { element: result }
}
).pop()
function RootWrappedWithOverlayAndProvider() {
return (
<FastRefreshOverlay>
<SliceDataStore>
<StaticQueryStore>{rootWrappedWithWrapRootElement}</StaticQueryStore>
</SliceDataStore>
</FastRefreshOverlay>
)
}
export default RootWrappedWithOverlayAndProvider