Skip to content

Commit 1f1f66a

Browse files
authored
feat: Add NextJS app router support (#3074)
1 parent e9048b8 commit 1f1f66a

26 files changed

+248
-17
lines changed

.changeset/many-rings-matter.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
'@data-client/ssr': patch
3+
---
4+
5+
Add DataProvider export to /nextjs namespace.
6+
7+
This provides 'App Router' compatibility. Simply add it to the root layout, ensuring
8+
`children` is rendered as a descendent.
9+
10+
<details open>
11+
<summary><b>app/layout.tsx</b></summary>
12+
13+
```tsx
14+
import { DataProvider } from '@data-client/react/nextjs';
15+
import { AsyncBoundary } from '@data-client/react';
16+
17+
export default function RootLayout({ children }) {
18+
return (
19+
<html>
20+
<body>
21+
<DataProvider>
22+
<header>Title</header>
23+
<AsyncBoundary>{children}</AsyncBoundary>
24+
<footer></footer>
25+
</DataProvider>
26+
</body>
27+
</html>
28+
);
29+
}
30+
```
31+
32+
</details>

.changeset/metal-birds-punch.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
'@data-client/use-enhanced-reducer': patch
3+
'@data-client/react': patch
4+
'@data-client/redux': patch
5+
'@data-client/ssr': patch
6+
---
7+
8+
Compatibility with server/client component build rules

examples/nextjs/tsconfig.json

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
{
22
"compilerOptions": {
33
"target": "es5",
4-
"lib": ["dom", "dom.iterable", "esnext"],
4+
"lib": [
5+
"dom",
6+
"dom.iterable",
7+
"esnext"
8+
],
59
"allowJs": true,
610
"skipLibCheck": true,
711
"strict": true,
@@ -13,8 +17,20 @@
1317
"resolveJsonModule": true,
1418
"isolatedModules": true,
1519
"jsx": "preserve",
16-
"incremental": true
20+
"incremental": true,
21+
"plugins": [
22+
{
23+
"name": "next"
24+
}
25+
]
1726
},
18-
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
19-
"exclude": ["node_modules"]
27+
"include": [
28+
"next-env.d.ts",
29+
"**/*.ts",
30+
"**/*.tsx",
31+
".next/types/**/*.ts"
32+
],
33+
"exclude": [
34+
"node_modules"
35+
]
2036
}

packages/react/src/components/CacheProvider.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
'use client';
12
import {
23
initialState as defaultState,
34
NetworkManager,

packages/react/src/components/ErrorBoundary.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
'use client';
12
import React from 'react';
23
import type { JSX } from 'react';
34

packages/react/src/context.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
'use client';
12
import { Controller, initialState } from '@data-client/core';
23
import type { ActionTypes, State } from '@data-client/core';
34
import { createContext } from 'react';
Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,27 @@
1+
'use client';
12
import type { State } from '@data-client/core';
2-
import React, { useContext } from 'react';
3+
import React from 'react';
34

5+
import use from './useUniversal.js';
46
import { StateContext, StoreContext } from '../context.js';
57

68
const useCacheState: () => State<unknown> =
9+
/* istanbul ignore if */
710
(
811
typeof window === 'undefined' &&
912
Object.hasOwn(React, 'useSyncExternalStore')
1013
) ?
14+
/* istanbul ignore next */
1115
() => {
12-
const store = useContext(StoreContext);
13-
const state = useContext(StateContext);
16+
const store = use(StoreContext);
17+
const state = use(StateContext);
1418
const syncState = React.useSyncExternalStore(
1519
store.subscribe,
1620
store.getState,
1721
store.getState,
1822
);
1923
return store.uninitialized ? state : syncState;
2024
}
21-
: () => useContext(StateContext);
25+
: () => use(StateContext);
2226

2327
export default useCacheState;
Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
1-
// Server Side Component compatibility (specifying this cannot be used as such)
2-
// context does not work in server components
3-
// https://beta.nextjs.org/docs/rendering/server-and-client-components#third-party-packages
4-
'use client';
51
import type { Controller } from '@data-client/core';
6-
import { useContext } from 'react';
72

3+
import use from './useUniversal.js';
84
import { ControllerContext } from '../context.js';
95

106
/**
117
* Imperative control of Reactive Data Client store
128
* @see https://dataclient.io/docs/api/useController
139
*/
1410
export default function useController(): Controller {
15-
return useContext(ControllerContext);
11+
return use(ControllerContext);
1612
}

packages/react/src/hooks/useDLE.native.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import type {
77
FetchFunction,
88
Schema,
99
ResolveType,
10-
NI,
1110
} from '@data-client/core';
1211
import { ExpiryStatus } from '@data-client/core';
1312
import { useMemo } from 'react';

packages/react/src/hooks/useDLE.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import type {
77
FetchFunction,
88
Schema,
99
ResolveType,
10-
NI,
1110
} from '@data-client/core';
1211
import { ExpiryStatus } from '@data-client/core';
1312
import { useMemo } from 'react';

0 commit comments

Comments
 (0)