-
Notifications
You must be signed in to change notification settings - Fork 26.3k
/
_app.tsx
129 lines (113 loc) · 3.64 KB
/
_app.tsx
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
import React, { ErrorInfo } from 'react'
import {
execOnce,
loadGetInitialProps,
AppContextType,
AppInitialProps,
AppPropsType,
NextWebVitalsMetric,
} from '../next-server/lib/utils'
import { Router } from '../client/router'
export { AppInitialProps }
export { NextWebVitalsMetric }
export type AppContext = AppContextType<Router>
export type AppProps<P = {}> = AppPropsType<Router, P>
/**
* `App` component is used for initialize of pages. It allows for overwriting and full control of the `page` initialization.
* This allows for keeping state between navigation, custom error handling, injecting additional data.
*/
async function appGetInitialProps({
Component,
ctx,
}: AppContext): Promise<AppInitialProps> {
const pageProps = await loadGetInitialProps(Component, ctx)
return { pageProps }
}
export default class App<P = {}, CP = {}, S = {}> extends React.Component<
P & AppProps<CP>,
S
> {
static origGetInitialProps = appGetInitialProps
static getInitialProps = appGetInitialProps
// Kept here for backwards compatibility.
// When someone ended App they could call `super.componentDidCatch`.
// @deprecated This method is no longer needed. Errors are caught at the top level
componentDidCatch(error: Error, _errorInfo: ErrorInfo): void {
throw error
}
render() {
const { router, Component, pageProps, __N_SSG, __N_SSP } = this
.props as AppProps<CP>
return (
<Component
{...pageProps}
{
// we don't add the legacy URL prop if it's using non-legacy
// methods like getStaticProps and getServerSideProps
...(!(__N_SSG || __N_SSP) ? { url: createUrl(router) } : {})
}
/>
)
}
}
let warnContainer: () => void
let warnUrl: () => void
if (process.env.NODE_ENV !== 'production') {
warnContainer = execOnce(() => {
console.warn(
`Warning: the \`Container\` in \`_app\` has been deprecated and should be removed. https://err.sh/vercel/next.js/app-container-deprecated`
)
})
warnUrl = execOnce(() => {
console.error(
`Warning: the 'url' property is deprecated. https://err.sh/vercel/next.js/url-deprecated`
)
})
}
// @deprecated noop for now until removal
export function Container(p: any) {
if (process.env.NODE_ENV !== 'production') warnContainer()
return p.children
}
export function createUrl(router: Router) {
// This is to make sure we don't references the router object at call time
const { pathname, asPath, query } = router
return {
get query() {
if (process.env.NODE_ENV !== 'production') warnUrl()
return query
},
get pathname() {
if (process.env.NODE_ENV !== 'production') warnUrl()
return pathname
},
get asPath() {
if (process.env.NODE_ENV !== 'production') warnUrl()
return asPath
},
back: () => {
if (process.env.NODE_ENV !== 'production') warnUrl()
router.back()
},
push: (url: string, as?: string) => {
if (process.env.NODE_ENV !== 'production') warnUrl()
return router.push(url, as)
},
pushTo: (href: string, as?: string) => {
if (process.env.NODE_ENV !== 'production') warnUrl()
const pushRoute = as ? href : ''
const pushUrl = as || href
return router.push(pushRoute, pushUrl)
},
replace: (url: string, as?: string) => {
if (process.env.NODE_ENV !== 'production') warnUrl()
return router.replace(url, as)
},
replaceTo: (href: string, as?: string) => {
if (process.env.NODE_ENV !== 'production') warnUrl()
const replaceRoute = as ? href : ''
const replaceUrl = as || href
return router.replace(replaceRoute, replaceUrl)
},
}
}