-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathwithServerContext.mjs
87 lines (78 loc) · 2.64 KB
/
withServerContext.mjs
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
// @ts-check
import nextApp from "next/app.js";
import React from "react";
import cjsDefaultImport from "./cjsDefaultImport.mjs";
import ServerContextContext from "./ServerContextContext.mjs";
const NextApp = cjsDefaultImport(nextApp);
/**
* Decorates a Next.js custom `App` or page React component, to provide
* {@link ServerContextContext server context}.
* @param {import("next").NextComponentType<
* import("next/app.js").AppContext | import("next").NextPageContext,
* any,
* any
* >} Component Next.js custom `App` or page React component.
* @returns Next.js custom `App` or page higher-order React component.
* @example
* A Next.js custom `App` in `pages/_app.js`:
*
* ```jsx
* import withServerContext from "next-server-context/withServerContext.mjs";
* import App from "next/app";
*
* export default withServerContext(App);
* ```
*/
export default function withServerContext(Component) {
/**
* Next.js custom `App` or page higher-order React component.
* @type {import("next").NextComponentType<
* import("next/app.js").AppContext | import("next").NextPageContext,
* {
* serverContext?: import("./ServerContextContext.mjs").ServerContext,
* [key: string]: unknown,
* },
* {
* serverContext?: import("./ServerContextContext.mjs").ServerContext,
* [key: string]: unknown,
* }
* >}
*/
const WithServerContext = ({ serverContext, ...props }) => {
return React.createElement(
ServerContextContext.Provider,
{ value: serverContext },
React.createElement(Component, props),
);
};
if (typeof process === "object" && process.env.NODE_ENV !== "production")
/**
* The display name.
* @see [React display name conventions](https://reactjs.org/docs/higher-order-components.html#convention-wrap-the-display-name-for-easy-debugging).
*/
WithServerContext.displayName = `WithServerContext(${
Component.displayName || Component.name || "Component"
})`;
WithServerContext.getInitialProps = async (context) => {
const isApp = "ctx" in context;
const { req, res } = isApp ? context.ctx : context;
const props = Component.getInitialProps
? await Component.getInitialProps(context)
: isApp
? await NextApp.getInitialProps(context)
: {};
return req
? {
...props,
serverContext: {
request: req,
response: res,
// This prevents the server attempting to serialize the server
// context object to JSON for hydration on the client.
toJSON: () => undefined,
},
}
: props;
};
return WithServerContext;
}