Skip to content

Commit 1e32f81

Browse files
authored
Fix getNextStaticProps and getNextServerSideProps to allow custom props (#545)
* fix: fixing typings for props so custom props do not result in a TypeScript error * chore: adding changeset * fix: lint
1 parent 9d4e02b commit 1e32f81

File tree

3 files changed

+82
-11
lines changed

3 files changed

+82
-11
lines changed

.changeset/polite-mails-rescue.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@faustjs/next': patch
3+
---
4+
5+
Typeings for `getNextStaticProps` and `getNextServerSideProps` now allow and protect custom props.

docs/next/guides/ssr-ssg.mdx

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,70 @@ export default function MyApp({ Component, pageProps }: AppProps) {
127127
);
128128
}
129129
```
130+
131+
## Configuring Custom Page Props And ISR
132+
133+
### Custom Page Props
134+
135+
If you need to send custom props to your page you can do so in the configuration options for both `getNextServerSideProps` and `getNextStaticProps`. Below is some example code demonstrating how to do this.
136+
137+
```tsx {2,5-9,14,26-28}
138+
import { GetStaticPropsContext } from 'next';
139+
import { getNextStaticProps } from '@faustjs/next';
140+
import { client } from 'client';
141+
142+
interface MyPageProps {
143+
title: string;
144+
}
145+
146+
export default function MyPage({ title }: MyPageProps) {
147+
const { usePosts } = client;
148+
149+
return (
150+
<>
151+
<h2>{title}</h2>
152+
{usePosts()?.nodes.map((post) => (
153+
<li key={post.id}>{post.title()}</li>
154+
))}
155+
</>
156+
);
157+
}
158+
159+
export async function getStaticProps(context: GetStaticPropsContext) {
160+
return getNextStaticProps(context, {
161+
Page: MyPage,
162+
client,
163+
props: {
164+
title: 'Recent Posts',
165+
},
166+
});
167+
}
168+
```
169+
170+
You might want to use this to send props down based on calls to APIs you make outside of Faust.js.
171+
172+
### Setting Up Incremental Static Regeneration (ISR)
173+
174+
Next.js enables ISR with [getStaticProps](https://nextjs.org/docs/basic-features/data-fetching#incremental-static-regeneration) using a `revalidate` property. By default in Next.js ISR is disabled. Faust.js enables ISR, and by default it sets it to 15 minutes. What this means is your page will be cached for 15 minutes before being regenerated. [Read more on the Next.js site about ISR](https://nextjs.org/docs/basic-features/data-fetching#incremental-static-regeneration).
175+
176+
With Faust.js you can configure ISR at both the page level and the global level. At the page level you can pass it along in the configuration options for `getNextStaticProps` as follows:
177+
178+
```ts {4}
179+
return getNextStaticProps(context, {
180+
Page: MyPage,
181+
client,
182+
revalidate: 60, // 60 seconds
183+
});
184+
```
185+
186+
To configure ISR at a global level you can add the following code to your `faust.config`:
187+
188+
```ts title=src/faust.config.js
189+
import { config as nextConfig } from '@faustjs/next';
190+
191+
nextConfig({
192+
revalidate: 60, // 60 seconds
193+
});
194+
```
195+
196+
The code above will set the default ISR revalidate time for every page, and can be overridden on each page.

packages/next/src/getProps.tsx

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,18 @@ export const AUTH_CLIENT_CACHE_PROP = '__AUTH_CLIENT_CACHE_PROP';
3030

3131
export interface GetNextServerSidePropsConfig<Props = Record<string, unknown>> {
3232
client: ReturnType<typeof getClient>;
33-
Page?: FunctionComponent | ComponentClass;
33+
Page?:
34+
| FunctionComponent<Props>
35+
| ComponentClass<Props>
36+
| ((props: Props) => JSX.Element);
3437
props?: Props;
3538
notFound?: boolean;
3639
redirect?: Redirect;
3740
}
3841

39-
export interface GetNextStaticPropsConfig<Props = Record<string, unknown>> {
40-
client: ReturnType<typeof getClient>;
41-
Page?: FunctionComponent | ComponentClass;
42-
props?: Props;
42+
export interface GetNextStaticPropsConfig<Props = Record<string, unknown>>
43+
extends GetNextServerSidePropsConfig<Props> {
4344
revalidate?: number | boolean;
44-
notFound?: boolean;
45-
redirect?: Redirect;
4645
}
4746

4847
export interface PageProps<Props> {
@@ -65,7 +64,7 @@ export async function getProps<
6564
client,
6665
Page,
6766
props,
68-
}: GetNextServerSidePropsConfig | GetNextStaticPropsConfig,
67+
}: GetNextServerSidePropsConfig<Props> | GetNextStaticPropsConfig<Props>,
6968
): Promise<PageProps<Props>> {
7069
let cacheSnapshot: string | undefined;
7170
let authSnapshot: string | undefined;
@@ -82,7 +81,7 @@ export async function getProps<
8281
value={{ query: { ...context.params } } as any}>
8382
<HeadlessContext.Provider value={{ client }}>
8483
{/* eslint-disable-next-line react/jsx-props-no-spreading */}
85-
<Page {...props} />
84+
<Page {...(props as Props)} />
8685
</HeadlessContext.Provider>
8786
</RouterContext.Provider>,
8887
);
@@ -210,7 +209,7 @@ export async function is404<
210209
*/
211210
export async function getNextServerSideProps<Props>(
212211
context: GetServerSidePropsContext,
213-
cfg: GetNextServerSidePropsConfig,
212+
cfg: GetNextServerSidePropsConfig<Props>,
214213
): Promise<GetServerSidePropsResult<Props>> {
215214
const { notFound, redirect } = cfg;
216215

@@ -238,7 +237,7 @@ export async function getNextServerSideProps<Props>(
238237
*/
239238
export async function getNextStaticProps<Props>(
240239
context: GetStaticPropsContext,
241-
cfg: GetNextStaticPropsConfig,
240+
cfg: GetNextStaticPropsConfig<Props>,
242241
): Promise<GetStaticPropsResult<Props>> {
243242
const { notFound, redirect, revalidate } = cfg;
244243
const nextConfig = config();

0 commit comments

Comments
 (0)