react-router 8.2.0 → 8.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +67 -0
- package/dist/development/dom-export.js +1 -1
- package/dist/development/index-react-server-client.js +1 -1
- package/dist/development/index-react-server.d.ts +106 -17
- package/dist/development/index-react-server.js +168 -42
- package/dist/development/index.js +1 -1
- package/dist/development/lib/actions.js +1 -1
- package/dist/development/lib/components.js +1 -1
- package/dist/development/lib/context.js +1 -1
- package/dist/development/lib/dom/dom.d.ts +24 -24
- package/dist/development/lib/dom/dom.js +25 -25
- package/dist/development/lib/dom/lib.d.ts +2 -1
- package/dist/development/lib/dom/lib.js +5 -4
- package/dist/development/lib/dom/server.js +1 -1
- package/dist/development/lib/dom/ssr/components.js +1 -1
- package/dist/development/lib/dom/ssr/data.js +1 -1
- package/dist/development/lib/dom/ssr/errorBoundaries.js +1 -1
- package/dist/development/lib/dom/ssr/fallback.js +1 -1
- package/dist/development/lib/dom/ssr/fog-of-war.js +26 -21
- package/dist/development/lib/dom/ssr/hydration.js +1 -1
- package/dist/development/lib/dom/ssr/invariant.js +1 -1
- package/dist/development/lib/dom/ssr/links.js +1 -1
- package/dist/development/lib/dom/ssr/markup.js +1 -1
- package/dist/development/lib/dom/ssr/routeModules.js +1 -1
- package/dist/development/lib/dom/ssr/routes-test-stub.d.ts +13 -0
- package/dist/development/lib/dom/ssr/routes-test-stub.js +14 -1
- package/dist/development/lib/dom/ssr/routes.js +1 -1
- package/dist/development/lib/dom/ssr/server.js +1 -1
- package/dist/development/lib/dom/ssr/single-fetch.js +1 -1
- package/dist/development/lib/dom-export/dom-router-provider.js +1 -1
- package/dist/development/lib/dom-export/hydrated-router.js +1 -1
- package/dist/development/lib/errors.js +1 -1
- package/dist/development/lib/hooks.js +1 -1
- package/dist/development/lib/href.d.ts +24 -8
- package/dist/development/lib/href.js +28 -11
- package/dist/development/lib/router/history.d.ts +6 -0
- package/dist/development/lib/router/history.js +7 -1
- package/dist/development/lib/router/instrumentation.js +1 -1
- package/dist/development/lib/router/router.js +1 -1
- package/dist/development/lib/router/url.js +1 -1
- package/dist/development/lib/router/utils.d.ts +12 -0
- package/dist/development/lib/router/utils.js +57 -3
- package/dist/development/lib/rsc/browser.js +34 -24
- package/dist/development/lib/rsc/errorBoundaries.js +1 -1
- package/dist/development/lib/rsc/html-stream/browser.js +1 -1
- package/dist/development/lib/rsc/html-stream/server.js +29 -10
- package/dist/development/lib/rsc/route-modules.js +1 -1
- package/dist/development/lib/rsc/server.rsc.d.ts +5 -1
- package/dist/development/lib/rsc/server.ssr.d.ts +29 -6
- package/dist/development/lib/rsc/server.ssr.js +27 -12
- package/dist/development/lib/server-runtime/cookies.d.ts +28 -2
- package/dist/development/lib/server-runtime/cookies.js +17 -3
- package/dist/development/lib/server-runtime/crypto.js +1 -1
- package/dist/development/lib/server-runtime/data.js +1 -1
- package/dist/development/lib/server-runtime/dev.js +1 -1
- package/dist/development/lib/server-runtime/entry.js +1 -1
- package/dist/development/lib/server-runtime/errors.js +1 -1
- package/dist/development/lib/server-runtime/headers.js +1 -1
- package/dist/development/lib/server-runtime/invariant.js +1 -1
- package/dist/development/lib/server-runtime/mode.js +1 -1
- package/dist/development/lib/server-runtime/routeMatching.js +1 -1
- package/dist/development/lib/server-runtime/routes.js +1 -1
- package/dist/development/lib/server-runtime/server.d.ts +12 -0
- package/dist/development/lib/server-runtime/server.js +13 -1
- package/dist/development/lib/server-runtime/serverHandoff.js +1 -1
- package/dist/development/lib/server-runtime/sessions/cookieStorage.d.ts +8 -0
- package/dist/development/lib/server-runtime/sessions/cookieStorage.js +9 -1
- package/dist/development/lib/server-runtime/sessions/memoryStorage.d.ts +10 -4
- package/dist/development/lib/server-runtime/sessions/memoryStorage.js +12 -6
- package/dist/development/lib/server-runtime/sessions.d.ts +31 -2
- package/dist/development/lib/server-runtime/sessions.js +20 -3
- package/dist/development/lib/server-runtime/single-fetch.js +1 -1
- package/dist/development/lib/server-runtime/urls.js +1 -1
- package/dist/development/lib/server-runtime/warnings.js +1 -1
- package/dist/development/lib/types/internal.js +1 -1
- package/dist/development/vendor/turbo-stream-v2/flatten.js +1 -1
- package/dist/development/vendor/turbo-stream-v2/turbo-stream.js +1 -1
- package/dist/development/vendor/turbo-stream-v2/unflatten.js +1 -1
- package/dist/development/vendor/turbo-stream-v2/utils.js +1 -1
- package/dist/production/dom-export.js +1 -1
- package/dist/production/index-react-server-client.js +1 -1
- package/dist/production/index-react-server.d.ts +106 -17
- package/dist/production/index-react-server.js +168 -42
- package/dist/production/index.js +1 -1
- package/dist/production/lib/actions.js +1 -1
- package/dist/production/lib/components.js +1 -1
- package/dist/production/lib/context.js +1 -1
- package/dist/production/lib/dom/dom.d.ts +24 -24
- package/dist/production/lib/dom/dom.js +25 -25
- package/dist/production/lib/dom/lib.d.ts +2 -1
- package/dist/production/lib/dom/lib.js +5 -4
- package/dist/production/lib/dom/server.js +1 -1
- package/dist/production/lib/dom/ssr/components.js +1 -1
- package/dist/production/lib/dom/ssr/data.js +1 -1
- package/dist/production/lib/dom/ssr/errorBoundaries.js +1 -1
- package/dist/production/lib/dom/ssr/fallback.js +1 -1
- package/dist/production/lib/dom/ssr/fog-of-war.js +26 -21
- package/dist/production/lib/dom/ssr/hydration.js +1 -1
- package/dist/production/lib/dom/ssr/invariant.js +1 -1
- package/dist/production/lib/dom/ssr/links.js +1 -1
- package/dist/production/lib/dom/ssr/markup.js +1 -1
- package/dist/production/lib/dom/ssr/routeModules.js +1 -1
- package/dist/production/lib/dom/ssr/routes-test-stub.d.ts +13 -0
- package/dist/production/lib/dom/ssr/routes-test-stub.js +14 -1
- package/dist/production/lib/dom/ssr/routes.js +1 -1
- package/dist/production/lib/dom/ssr/server.js +1 -1
- package/dist/production/lib/dom/ssr/single-fetch.js +1 -1
- package/dist/production/lib/dom-export/dom-router-provider.js +1 -1
- package/dist/production/lib/dom-export/hydrated-router.js +1 -1
- package/dist/production/lib/errors.js +1 -1
- package/dist/production/lib/hooks.js +1 -1
- package/dist/production/lib/href.d.ts +24 -8
- package/dist/production/lib/href.js +28 -11
- package/dist/production/lib/router/history.d.ts +6 -0
- package/dist/production/lib/router/history.js +7 -1
- package/dist/production/lib/router/instrumentation.js +1 -1
- package/dist/production/lib/router/router.js +1 -1
- package/dist/production/lib/router/url.js +1 -1
- package/dist/production/lib/router/utils.d.ts +12 -0
- package/dist/production/lib/router/utils.js +57 -3
- package/dist/production/lib/rsc/browser.js +34 -24
- package/dist/production/lib/rsc/errorBoundaries.js +1 -1
- package/dist/production/lib/rsc/html-stream/browser.js +1 -1
- package/dist/production/lib/rsc/html-stream/server.js +29 -10
- package/dist/production/lib/rsc/route-modules.js +1 -1
- package/dist/production/lib/rsc/server.rsc.d.ts +5 -1
- package/dist/production/lib/rsc/server.ssr.d.ts +29 -6
- package/dist/production/lib/rsc/server.ssr.js +27 -12
- package/dist/production/lib/server-runtime/cookies.d.ts +28 -2
- package/dist/production/lib/server-runtime/cookies.js +17 -3
- package/dist/production/lib/server-runtime/crypto.js +1 -1
- package/dist/production/lib/server-runtime/data.js +1 -1
- package/dist/production/lib/server-runtime/dev.js +1 -1
- package/dist/production/lib/server-runtime/entry.js +1 -1
- package/dist/production/lib/server-runtime/errors.js +1 -1
- package/dist/production/lib/server-runtime/headers.js +1 -1
- package/dist/production/lib/server-runtime/invariant.js +1 -1
- package/dist/production/lib/server-runtime/mode.js +1 -1
- package/dist/production/lib/server-runtime/routeMatching.js +1 -1
- package/dist/production/lib/server-runtime/routes.js +1 -1
- package/dist/production/lib/server-runtime/server.d.ts +12 -0
- package/dist/production/lib/server-runtime/server.js +13 -1
- package/dist/production/lib/server-runtime/serverHandoff.js +1 -1
- package/dist/production/lib/server-runtime/sessions/cookieStorage.d.ts +8 -0
- package/dist/production/lib/server-runtime/sessions/cookieStorage.js +9 -1
- package/dist/production/lib/server-runtime/sessions/memoryStorage.d.ts +10 -4
- package/dist/production/lib/server-runtime/sessions/memoryStorage.js +12 -6
- package/dist/production/lib/server-runtime/sessions.d.ts +31 -2
- package/dist/production/lib/server-runtime/sessions.js +20 -3
- package/dist/production/lib/server-runtime/single-fetch.js +1 -1
- package/dist/production/lib/server-runtime/urls.js +1 -1
- package/dist/production/lib/server-runtime/warnings.js +1 -1
- package/dist/production/lib/types/internal.js +1 -1
- package/dist/production/vendor/turbo-stream-v2/flatten.js +1 -1
- package/dist/production/vendor/turbo-stream-v2/turbo-stream.js +1 -1
- package/dist/production/vendor/turbo-stream-v2/unflatten.js +1 -1
- package/dist/production/vendor/turbo-stream-v2/utils.js +1 -1
- package/docs/explanation/sessions-and-cookies.md +13 -13
- package/docs/explanation/state-management.md +2 -2
- package/docs/how-to/presets.md +2 -2
- package/docs/how-to/react-server-components.md +53 -1
- package/docs/how-to/security.md +8 -1
- package/docs/how-to/server-bundles.md +2 -2
- package/docs/start/data/route-object.md +2 -2
- package/docs/start/data/routing.md +1 -1
- package/docs/start/framework/pending-ui.md +1 -1
- package/docs/start/framework/route-module.md +8 -8
- package/docs/start/framework/routing.md +1 -1
- package/package.json +1 -1
|
@@ -5,6 +5,18 @@ import { ServerBuild } from "./build.js";
|
|
|
5
5
|
//#region lib/server-runtime/server.d.ts
|
|
6
6
|
type RequestHandler = (request: Request, loadContext?: RouterContextProvider) => Promise<Response>;
|
|
7
7
|
type CreateRequestHandlerFunction = (build: ServerBuild | (() => ServerBuild | Promise<ServerBuild>), mode?: string) => RequestHandler;
|
|
8
|
+
/**
|
|
9
|
+
* Creates a request handler for a React Router server build.
|
|
10
|
+
*
|
|
11
|
+
* This is a low-level API used by server adapters to translate incoming
|
|
12
|
+
* requests into React Router responses.
|
|
13
|
+
*
|
|
14
|
+
* @category Utils
|
|
15
|
+
* @param build The server build, or a function that resolves to the server
|
|
16
|
+
* build, used to handle requests.
|
|
17
|
+
* @param mode The mode in which the server build is running.
|
|
18
|
+
* @returns A request handler that returns a response for each incoming request.
|
|
19
|
+
*/
|
|
8
20
|
declare const createRequestHandler: CreateRequestHandlerFunction;
|
|
9
21
|
//#endregion
|
|
10
22
|
export { CreateRequestHandlerFunction, RequestHandler, createRequestHandler };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.
|
|
2
|
+
* react-router v8.3.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -137,6 +137,18 @@ function derive(build, mode) {
|
|
|
137
137
|
requestHandler
|
|
138
138
|
};
|
|
139
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* Creates a request handler for a React Router server build.
|
|
142
|
+
*
|
|
143
|
+
* This is a low-level API used by server adapters to translate incoming
|
|
144
|
+
* requests into React Router responses.
|
|
145
|
+
*
|
|
146
|
+
* @category Utils
|
|
147
|
+
* @param build The server build, or a function that resolves to the server
|
|
148
|
+
* build, used to handle requests.
|
|
149
|
+
* @param mode The mode in which the server build is running.
|
|
150
|
+
* @returns A request handler that returns a response for each incoming request.
|
|
151
|
+
*/
|
|
140
152
|
const createRequestHandler = (build, mode) => {
|
|
141
153
|
let _build;
|
|
142
154
|
let serverMode;
|
|
@@ -17,6 +17,14 @@ interface CookieSessionStorageOptions {
|
|
|
17
17
|
* needed, and can help to simplify some load-balanced scenarios. However, it
|
|
18
18
|
* also has the limitation that serialized session data may not exceed the
|
|
19
19
|
* browser's maximum cookie size. Trade-offs!
|
|
20
|
+
*
|
|
21
|
+
* @public
|
|
22
|
+
* @category Utils
|
|
23
|
+
* @mode framework
|
|
24
|
+
* @mode data
|
|
25
|
+
* @param options Options for creating the cookie-backed session storage.
|
|
26
|
+
* @returns A {@link SessionStorage} object that stores all session data in its
|
|
27
|
+
* cookie.
|
|
20
28
|
*/
|
|
21
29
|
declare function createCookieSessionStorage<Data = SessionData, FlashData = Data>({
|
|
22
30
|
cookie: cookieArg
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.
|
|
2
|
+
* react-router v8.3.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -19,6 +19,14 @@ import { createSession, warnOnceAboutSigningSessionCookie } from "../sessions.js
|
|
|
19
19
|
* needed, and can help to simplify some load-balanced scenarios. However, it
|
|
20
20
|
* also has the limitation that serialized session data may not exceed the
|
|
21
21
|
* browser's maximum cookie size. Trade-offs!
|
|
22
|
+
*
|
|
23
|
+
* @public
|
|
24
|
+
* @category Utils
|
|
25
|
+
* @mode framework
|
|
26
|
+
* @mode data
|
|
27
|
+
* @param options Options for creating the cookie-backed session storage.
|
|
28
|
+
* @returns A {@link SessionStorage} object that stores all session data in its
|
|
29
|
+
* cookie.
|
|
22
30
|
*/
|
|
23
31
|
function createCookieSessionStorage({ cookie: cookieArg } = {}) {
|
|
24
32
|
let cookie = isCookie(cookieArg) ? cookieArg : createCookie(cookieArg?.name || "__session", cookieArg);
|
|
@@ -10,11 +10,17 @@ interface MemorySessionStorageOptions {
|
|
|
10
10
|
cookie?: SessionIdStorageStrategy["cookie"];
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
|
-
* Creates and returns a simple in-memory SessionStorage object
|
|
14
|
-
* for testing and as a reference implementation.
|
|
13
|
+
* Creates and returns a simple in-memory SessionStorage object.
|
|
15
14
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
15
|
+
* Intended for local development and testing. It does not scale beyond a single
|
|
16
|
+
* process, and all session data is lost when the server process stops/restarts.
|
|
17
|
+
*
|
|
18
|
+
* @public
|
|
19
|
+
* @category Utils
|
|
20
|
+
* @mode framework
|
|
21
|
+
* @mode data
|
|
22
|
+
* @param options Options for creating the in-memory session storage.
|
|
23
|
+
* @returns A {@link SessionStorage} object that stores session data in memory.
|
|
18
24
|
*/
|
|
19
25
|
declare function createMemorySessionStorage<Data = SessionData, FlashData = Data>({
|
|
20
26
|
cookie
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.
|
|
2
|
+
* react-router v8.3.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -11,18 +11,24 @@
|
|
|
11
11
|
import { createSessionStorage } from "../sessions.js";
|
|
12
12
|
//#region lib/server-runtime/sessions/memoryStorage.ts
|
|
13
13
|
/**
|
|
14
|
-
* Creates and returns a simple in-memory SessionStorage object
|
|
15
|
-
* for testing and as a reference implementation.
|
|
14
|
+
* Creates and returns a simple in-memory SessionStorage object.
|
|
16
15
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
16
|
+
* Intended for local development and testing. It does not scale beyond a single
|
|
17
|
+
* process, and all session data is lost when the server process stops/restarts.
|
|
18
|
+
*
|
|
19
|
+
* @public
|
|
20
|
+
* @category Utils
|
|
21
|
+
* @mode framework
|
|
22
|
+
* @mode data
|
|
23
|
+
* @param options Options for creating the in-memory session storage.
|
|
24
|
+
* @returns A {@link SessionStorage} object that stores session data in memory.
|
|
19
25
|
*/
|
|
20
26
|
function createMemorySessionStorage({ cookie } = {}) {
|
|
21
27
|
let map = /* @__PURE__ */ new Map();
|
|
22
28
|
return createSessionStorage({
|
|
23
29
|
cookie,
|
|
24
30
|
async createData(data, expires) {
|
|
25
|
-
let id =
|
|
31
|
+
let id = crypto.randomUUID();
|
|
26
32
|
map.set(id, {
|
|
27
33
|
data,
|
|
28
34
|
expires
|
|
@@ -60,13 +60,37 @@ type CreateSessionFunction = <Data = SessionData, FlashData = Data>(initialData?
|
|
|
60
60
|
*
|
|
61
61
|
* Note: This function is typically not invoked directly by application code.
|
|
62
62
|
* Instead, use a `SessionStorage` object's `getSession` method.
|
|
63
|
+
*
|
|
64
|
+
* @category Utils
|
|
65
|
+
* @param initialData The initial data for the session.
|
|
66
|
+
* @param id The identifier for the session. Defaults to an empty string for a
|
|
67
|
+
* new session.
|
|
68
|
+
* @returns A new {@link Session} object.
|
|
63
69
|
*/
|
|
64
70
|
declare const createSession: CreateSessionFunction;
|
|
71
|
+
/**
|
|
72
|
+
* A function that determines whether a value is a React Router {@link Session}
|
|
73
|
+
* object.
|
|
74
|
+
*
|
|
75
|
+
* @public
|
|
76
|
+
* @category Utils
|
|
77
|
+
* @mode framework
|
|
78
|
+
* @mode data
|
|
79
|
+
* @param object The value to check.
|
|
80
|
+
* @returns `true` if the value is a React Router {@link Session} object;
|
|
81
|
+
* otherwise, `false`.
|
|
82
|
+
*/
|
|
65
83
|
type IsSessionFunction = (object: any) => object is Session;
|
|
66
84
|
/**
|
|
67
|
-
* Returns true if
|
|
85
|
+
* Returns `true` if a value is a React Router {@link Session} object.
|
|
68
86
|
*
|
|
69
|
-
* @
|
|
87
|
+
* @public
|
|
88
|
+
* @category Utils
|
|
89
|
+
* @mode framework
|
|
90
|
+
* @mode data
|
|
91
|
+
* @param object The value to check.
|
|
92
|
+
* @returns `true` if the value is a React Router {@link Session} object;
|
|
93
|
+
* otherwise, `false`.
|
|
70
94
|
*/
|
|
71
95
|
declare const isSession: IsSessionFunction;
|
|
72
96
|
/**
|
|
@@ -133,6 +157,11 @@ interface SessionIdStorageStrategy<Data = SessionData, FlashData = Data> {
|
|
|
133
157
|
*
|
|
134
158
|
* Note: This is a low-level API that should only be used if none of the
|
|
135
159
|
* existing session storage options meet your requirements.
|
|
160
|
+
*
|
|
161
|
+
* @category Utils
|
|
162
|
+
* @param strategy The strategy used to store session identifiers and data.
|
|
163
|
+
* @returns A {@link SessionStorage} object that persists session data using the
|
|
164
|
+
* provided strategy.
|
|
136
165
|
*/
|
|
137
166
|
declare function createSessionStorage<Data = SessionData, FlashData = Data>({
|
|
138
167
|
cookie: cookieArg,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.
|
|
2
|
+
* react-router v8.3.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -19,6 +19,12 @@ function flash(name) {
|
|
|
19
19
|
*
|
|
20
20
|
* Note: This function is typically not invoked directly by application code.
|
|
21
21
|
* Instead, use a `SessionStorage` object's `getSession` method.
|
|
22
|
+
*
|
|
23
|
+
* @category Utils
|
|
24
|
+
* @param initialData The initial data for the session.
|
|
25
|
+
* @param id The identifier for the session. Defaults to an empty string for a
|
|
26
|
+
* new session.
|
|
27
|
+
* @returns A new {@link Session} object.
|
|
22
28
|
*/
|
|
23
29
|
const createSession = (initialData = {}, id = "") => {
|
|
24
30
|
let map = new Map(Object.entries(initialData));
|
|
@@ -53,9 +59,15 @@ const createSession = (initialData = {}, id = "") => {
|
|
|
53
59
|
};
|
|
54
60
|
};
|
|
55
61
|
/**
|
|
56
|
-
* Returns true if
|
|
62
|
+
* Returns `true` if a value is a React Router {@link Session} object.
|
|
57
63
|
*
|
|
58
|
-
* @
|
|
64
|
+
* @public
|
|
65
|
+
* @category Utils
|
|
66
|
+
* @mode framework
|
|
67
|
+
* @mode data
|
|
68
|
+
* @param object The value to check.
|
|
69
|
+
* @returns `true` if the value is a React Router {@link Session} object;
|
|
70
|
+
* otherwise, `false`.
|
|
59
71
|
*/
|
|
60
72
|
const isSession = (object) => {
|
|
61
73
|
return object != null && typeof object.id === "string" && typeof object.data !== "undefined" && typeof object.has === "function" && typeof object.get === "function" && typeof object.set === "function" && typeof object.flash === "function" && typeof object.unset === "function";
|
|
@@ -65,6 +77,11 @@ const isSession = (object) => {
|
|
|
65
77
|
*
|
|
66
78
|
* Note: This is a low-level API that should only be used if none of the
|
|
67
79
|
* existing session storage options meet your requirements.
|
|
80
|
+
*
|
|
81
|
+
* @category Utils
|
|
82
|
+
* @param strategy The strategy used to store session identifiers and data.
|
|
83
|
+
* @returns A {@link SessionStorage} object that persists session data using the
|
|
84
|
+
* provided strategy.
|
|
68
85
|
*/
|
|
69
86
|
function createSessionStorage({ cookie: cookieArg, createData, readData, updateData, deleteData }) {
|
|
70
87
|
let cookie = isCookie(cookieArg) ? cookieArg : createCookie(cookieArg?.name || "__session", cookieArg);
|
|
@@ -278,7 +278,7 @@ The `expires` argument to `createData` and `updateData` is the same `Date` at wh
|
|
|
278
278
|
There are also several other session utilities available if you need them:
|
|
279
279
|
|
|
280
280
|
- [`isSession`][is-session]
|
|
281
|
-
- [`createMemorySessionStorage`][create-memory-session-storage]
|
|
281
|
+
- [`createMemorySessionStorage`][create-memory-session-storage] (local dev and testing)
|
|
282
282
|
- [`createSession`][create-session] (custom storage)
|
|
283
283
|
- [`createFileSessionStorage`][create-file-session-storage] (node)
|
|
284
284
|
- [`createWorkersKVSessionStorage`][create-workers-kv-session-storage] (Cloudflare Workers)
|
|
@@ -449,17 +449,17 @@ To learn more about each attribute, please see the [MDN Set-Cookie docs][cookie-
|
|
|
449
449
|
[csrf]: https://developer.mozilla.org/en-US/docs/Glossary/CSRF
|
|
450
450
|
[cookies]: #cookies
|
|
451
451
|
[sessions]: #sessions
|
|
452
|
-
[session-storage]: https://api.reactrouter.com/
|
|
453
|
-
[session-api]: https://api.reactrouter.com/
|
|
454
|
-
[is-session]: https://api.reactrouter.com/
|
|
455
|
-
[cookie-api]: https://api.reactrouter.com/
|
|
456
|
-
[create-session-storage]: https://api.reactrouter.com/
|
|
457
|
-
[create-session]: https://api.reactrouter.com/
|
|
458
|
-
[create-memory-session-storage]: https://api.reactrouter.com/
|
|
459
|
-
[create-file-session-storage]: https://api.reactrouter.com/
|
|
460
|
-
[create-workers-kv-session-storage]: https://api.reactrouter.com/
|
|
461
|
-
[create-arc-table-session-storage]: https://api.reactrouter.com/
|
|
452
|
+
[session-storage]: https://api.reactrouter.com/v8/interfaces/react-router.SessionStorage
|
|
453
|
+
[session-api]: https://api.reactrouter.com/v8/interfaces/react-router.Session
|
|
454
|
+
[is-session]: https://api.reactrouter.com/v8/variables/react-router.isSession.html
|
|
455
|
+
[cookie-api]: https://api.reactrouter.com/v8/interfaces/react-router.Cookie
|
|
456
|
+
[create-session-storage]: https://api.reactrouter.com/v8/functions/react-router.createSessionStorage
|
|
457
|
+
[create-session]: https://api.reactrouter.com/v8/variables/react-router.createSession.html
|
|
458
|
+
[create-memory-session-storage]: https://api.reactrouter.com/v8/functions/react-router.createMemorySessionStorage
|
|
459
|
+
[create-file-session-storage]: https://api.reactrouter.com/v8/functions/_react-router_node.createFileSessionStorage
|
|
460
|
+
[create-workers-kv-session-storage]: https://api.reactrouter.com/v8/functions/_react-router_cloudflare.createWorkersKVSessionStorage
|
|
461
|
+
[create-arc-table-session-storage]: https://api.reactrouter.com/v8/functions/_react-router_architect.createArcTableSessionStorage
|
|
462
462
|
[cookie]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies
|
|
463
463
|
[cookie-attrs]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#attributes
|
|
464
|
-
[is-cookie]: https://api.reactrouter.com/
|
|
465
|
-
[create-cookie]: https://api.reactrouter.com/
|
|
464
|
+
[is-cookie]: https://api.reactrouter.com/v8/variables/react-router.isCookie.html
|
|
465
|
+
[create-cookie]: https://api.reactrouter.com/v8/functions/react-router.createCookie
|
|
@@ -510,8 +510,8 @@ If you ever find yourself entangled in managing and synchronizing state for netw
|
|
|
510
510
|
[redux]: https://redux.js.org/
|
|
511
511
|
[tanstack_query]: https://tanstack.com/query/latest
|
|
512
512
|
[apollo]: https://www.apollographql.com/
|
|
513
|
-
[use_navigation]: https://api.reactrouter.com/
|
|
514
|
-
[use_fetcher]: https://api.reactrouter.com/
|
|
513
|
+
[use_navigation]: https://api.reactrouter.com/v8/functions/react-router.useNavigation
|
|
514
|
+
[use_fetcher]: https://api.reactrouter.com/v8/functions/react-router.useFetcher
|
|
515
515
|
[loader_data]: ../start/framework/data-loading
|
|
516
516
|
[action_data]: ../start/framework/actions
|
|
517
517
|
[cookies]: ./sessions-and-cookies#cookies
|
package/docs/how-to/presets.md
CHANGED
|
@@ -98,6 +98,6 @@ export default {
|
|
|
98
98
|
} satisfies Config;
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
-
[react-router-config]: https://api.reactrouter.com/
|
|
102
|
-
[preset-type]: https://api.reactrouter.com/
|
|
101
|
+
[react-router-config]: https://api.reactrouter.com/v8/types/_react-router_dev.config.Config.html
|
|
102
|
+
[preset-type]: https://api.reactrouter.com/v8/types/_react-router_dev.config.Preset.html
|
|
103
103
|
[server-bundles]: ./server-bundles
|
|
@@ -385,7 +385,6 @@ The following options from `react-router.config.ts` are not currently supported
|
|
|
385
385
|
- `presets`
|
|
386
386
|
- `serverBundles`
|
|
387
387
|
- `splitRouteModules`
|
|
388
|
-
- `subResourceIntegrity`
|
|
389
388
|
|
|
390
389
|
## RSC Data Mode
|
|
391
390
|
|
|
@@ -868,7 +867,60 @@ createFromReadableStream<RSCPayload>(getRSCStream()).then(
|
|
|
868
867
|
);
|
|
869
868
|
```
|
|
870
869
|
|
|
870
|
+
## Content Security Policy nonces
|
|
871
|
+
|
|
872
|
+
A [Content Security Policy][csp] can use a per-response nonce to allow the inline scripts required for RSC hydration without allowing arbitrary inline scripts. The nonce is an HTML concern, so configure it in `entry.ssr.tsx`; it does not need to be passed to `matchRSCServerRequest` or included in the RSC payload.
|
|
873
|
+
|
|
874
|
+
In RSC Framework Mode, first run `react-router reveal entry.ssr` to create a custom SSR entry. In RSC Data Mode, update your existing SSR entry. Generate a fresh nonce for each document response, then pass it to `routeRSCServerRequest`, the `RSCStaticRouter`, and your CSP response header:
|
|
875
|
+
|
|
876
|
+
```tsx filename=app/entry.ssr.tsx
|
|
877
|
+
export async function generateHTML(
|
|
878
|
+
request: Request,
|
|
879
|
+
serverResponse: Response,
|
|
880
|
+
): Promise<Response> {
|
|
881
|
+
const nonce = crypto.randomUUID();
|
|
882
|
+
|
|
883
|
+
const response = await routeRSCServerRequest({
|
|
884
|
+
request,
|
|
885
|
+
serverResponse,
|
|
886
|
+
createFromReadableStream,
|
|
887
|
+
nonce,
|
|
888
|
+
async renderHTML(getPayload, options) {
|
|
889
|
+
const payload = getPayload();
|
|
890
|
+
const bootstrapScriptContent =
|
|
891
|
+
await import.meta.viteRsc.loadBootstrapScriptContent(
|
|
892
|
+
"index",
|
|
893
|
+
);
|
|
894
|
+
|
|
895
|
+
return renderHTMLToReadableStream(
|
|
896
|
+
<RSCStaticRouter
|
|
897
|
+
getPayload={getPayload}
|
|
898
|
+
nonce={options.nonce}
|
|
899
|
+
/>,
|
|
900
|
+
{
|
|
901
|
+
...options,
|
|
902
|
+
bootstrapScriptContent,
|
|
903
|
+
formState: await payload.formState,
|
|
904
|
+
signal: request.signal,
|
|
905
|
+
},
|
|
906
|
+
);
|
|
907
|
+
},
|
|
908
|
+
});
|
|
909
|
+
|
|
910
|
+
response.headers.set(
|
|
911
|
+
"Content-Security-Policy",
|
|
912
|
+
`script-src 'self' 'nonce-${nonce}'`,
|
|
913
|
+
);
|
|
914
|
+
return response;
|
|
915
|
+
}
|
|
916
|
+
```
|
|
917
|
+
|
|
918
|
+
The `nonce` option on `routeRSCServerRequest` applies the nonce to the inline scripts that transfer the RSC payload into the HTML document. Spreading its `renderHTML` options into `renderHTMLToReadableStream` applies the same nonce to scripts generated by React. Passing it to `RSCStaticRouter` makes it the default for nonce-aware components such as `<Links>` and `<ScrollRestoration>`.
|
|
919
|
+
|
|
920
|
+
The default RSC Framework entry does not generate a nonce. Only generate one when your application also sends a matching CSP header. For statically prerendered pages, prefer CSP hashes or external scripts instead of a per-response nonce.
|
|
921
|
+
|
|
871
922
|
[picking-a-mode]: ../start/modes
|
|
923
|
+
[csp]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP
|
|
872
924
|
[react-server-components-doc]: https://react.dev/reference/rsc/server-components
|
|
873
925
|
[react-server-functions-doc]: https://react.dev/reference/rsc/server-functions
|
|
874
926
|
[use-client-docs]: https://react.dev/reference/rsc/use-client
|
package/docs/how-to/security.md
CHANGED
|
@@ -4,7 +4,7 @@ title: Security
|
|
|
4
4
|
|
|
5
5
|
# Security
|
|
6
6
|
|
|
7
|
-
[MODES: framework]
|
|
7
|
+
[MODES: framework, data]
|
|
8
8
|
|
|
9
9
|
<br/>
|
|
10
10
|
<br/>
|
|
@@ -13,6 +13,8 @@ This is by no means a comprehensive guide, but React Router provides features to
|
|
|
13
13
|
|
|
14
14
|
## `Content-Security-Policy`
|
|
15
15
|
|
|
16
|
+
### Framework Mode without RSC
|
|
17
|
+
|
|
16
18
|
If you are implementing a [Content-Security-Policy (CSP)][csp] in your application, specifically one using the `unsafe-inline` directive, you will need to specify a [`nonce`][nonce] attribute on the inline `<script>` elements rendered in your HTML.
|
|
17
19
|
|
|
18
20
|
Add a nonce to these two spots in [`entry.server.tsx`][entryserver]:
|
|
@@ -22,6 +24,10 @@ Add a nonce to these two spots in [`entry.server.tsx`][entryserver]:
|
|
|
22
24
|
- If those components specify their own `nonce` prop, it will override the `ServerRouter` value
|
|
23
25
|
- The `nonce` options of [`renderToPipeableStream`][renderToPipeableStream]/[`renderToReadableStream`][renderToReadableStream]
|
|
24
26
|
|
|
27
|
+
### RSC Framework and RSC Data Mode
|
|
28
|
+
|
|
29
|
+
For RSC Framework and RSC Data Mode, generate the nonce in `entry.ssr.tsx` and pass it to `routeRSCServerRequest`, `RSCStaticRouter`, and the CSP response header. See the [RSC Content Security Policy nonce guide][rsc-csp]. The nonce is only needed while generating the HTML document; it should not be included in the RSC payload or passed to `matchRSCServerRequest`.
|
|
30
|
+
|
|
25
31
|
[csp]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP
|
|
26
32
|
[entryserver]: ../api/framework-conventions/entry.server.tsx
|
|
27
33
|
[nonce]: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/nonce
|
|
@@ -30,3 +36,4 @@ Add a nonce to these two spots in [`entry.server.tsx`][entryserver]:
|
|
|
30
36
|
[scripts]: ../api/components/Scripts
|
|
31
37
|
[scrollrestoration]: ../api/components/ScrollRestoration
|
|
32
38
|
[serverrouter]: ../api/framework-routers/ServerRouter
|
|
39
|
+
[rsc-csp]: ./react-server-components#content-security-policy-nonces
|
|
@@ -62,5 +62,5 @@ When using server bundles, the build manifest contains the following properties:
|
|
|
62
62
|
- `routeIdToServerBundleId` — An object that maps route IDs to their server bundle ID
|
|
63
63
|
- `routes` — A route manifest that maps route IDs to route metadata. This can be used to drive a custom routing layer in front of your React Router request handlers
|
|
64
64
|
|
|
65
|
-
[react-router-config]: https://api.reactrouter.com/
|
|
66
|
-
[server-bundles-function]: https://api.reactrouter.com/
|
|
65
|
+
[react-router-config]: https://api.reactrouter.com/v8/types/_react-router_dev.config.Config.html
|
|
66
|
+
[server-bundles-function]: https://api.reactrouter.com/v8/types/_react-router_dev.config.ServerBundlesFunction.html
|
|
@@ -216,7 +216,7 @@ createBrowserRouter([
|
|
|
216
216
|
]);
|
|
217
217
|
```
|
|
218
218
|
|
|
219
|
-
[`ShouldRevalidateFunctionArgs` Reference Documentation ↗](https://api.reactrouter.com/
|
|
219
|
+
[`ShouldRevalidateFunctionArgs` Reference Documentation ↗](https://api.reactrouter.com/v8/interfaces/react-router.ShouldRevalidateFunctionArgs.html)
|
|
220
220
|
|
|
221
221
|
Please note the default behavior is different in [Framework Mode](../modes).
|
|
222
222
|
|
|
@@ -263,6 +263,6 @@ See also:
|
|
|
263
263
|
|
|
264
264
|
Next: [Data Loading](./data-loading)
|
|
265
265
|
|
|
266
|
-
[loader-params]: https://api.reactrouter.com/
|
|
266
|
+
[loader-params]: https://api.reactrouter.com/v8/interfaces/react-router.LoaderFunctionArgs
|
|
267
267
|
[middleware]: ../../how-to/middleware
|
|
268
268
|
[use-matches]: ../../api/hooks/useMatches
|
|
@@ -500,27 +500,27 @@ export function shouldRevalidate(
|
|
|
500
500
|
|
|
501
501
|
When using [SPA Mode][spa-mode], there are no server loaders to call on navigations, so `shouldRevalidate` behaves the same as it does in [Data Mode][data-mode-should-revalidate].
|
|
502
502
|
|
|
503
|
-
[`ShouldRevalidateFunctionArgs` Reference Documentation ↗](https://api.reactrouter.com/
|
|
503
|
+
[`ShouldRevalidateFunctionArgs` Reference Documentation ↗](https://api.reactrouter.com/v8/interfaces/react-router.ShouldRevalidateFunctionArgs.html)
|
|
504
504
|
|
|
505
505
|
---
|
|
506
506
|
|
|
507
507
|
Next: [Rendering Strategies](./rendering)
|
|
508
508
|
|
|
509
|
-
[middleware-params]: https://api.reactrouter.com/
|
|
509
|
+
[middleware-params]: https://api.reactrouter.com/v8/types/react-router.MiddlewareFunction.html
|
|
510
510
|
[middleware]: ../../how-to/middleware
|
|
511
511
|
[when-middleware-runs]: ../../how-to/middleware#when-middleware-runs
|
|
512
|
-
[loader-params]: https://api.reactrouter.com/
|
|
513
|
-
[client-loader-params]: https://api.reactrouter.com/
|
|
514
|
-
[action-params]: https://api.reactrouter.com/
|
|
515
|
-
[client-action-params]: https://api.reactrouter.com/
|
|
512
|
+
[loader-params]: https://api.reactrouter.com/v8/interfaces/react-router.LoaderFunctionArgs
|
|
513
|
+
[client-loader-params]: https://api.reactrouter.com/v8/types/react-router.ClientLoaderFunctionArgs
|
|
514
|
+
[action-params]: https://api.reactrouter.com/v8/interfaces/react-router.ActionFunctionArgs
|
|
515
|
+
[client-action-params]: https://api.reactrouter.com/v8/types/react-router.ClientActionFunctionArgs
|
|
516
516
|
[use-route-error]: ../../api/hooks/useRouteError
|
|
517
517
|
[is-route-error-response]: ../../api/utils/isRouteErrorResponse
|
|
518
518
|
[headers]: https://developer.mozilla.org/en-US/docs/Web/API/Response/headers
|
|
519
519
|
[use-matches]: ../../api/hooks/useMatches
|
|
520
520
|
[link-element]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link
|
|
521
521
|
[meta-element]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta
|
|
522
|
-
[meta-params]: https://api.reactrouter.com/
|
|
523
|
-
[meta-function]: https://api.reactrouter.com/
|
|
522
|
+
[meta-params]: https://api.reactrouter.com/v8/interfaces/react-router.MetaArgs
|
|
523
|
+
[meta-function]: https://api.reactrouter.com/v8/types/react-router.MetaDescriptor.html
|
|
524
524
|
[data-mode-should-revalidate]: ../data/route-object#shouldrevalidate
|
|
525
525
|
[spa-mode]: ../../how-to/spa
|
|
526
526
|
[client-data]: ../../how-to/client-data
|
|
@@ -359,4 +359,4 @@ Note that these routes do not participate in data loading, actions, code splitti
|
|
|
359
359
|
Next: [Route Module](./route-module)
|
|
360
360
|
|
|
361
361
|
[file-route-conventions]: ../../how-to/file-route-conventions
|
|
362
|
-
[outlet]: https://api.reactrouter.com/
|
|
362
|
+
[outlet]: https://api.reactrouter.com/v8/functions/react-router.Outlet.html
|