Skip to content

Commit 0bbc72b

Browse files
Eliminate build-time API calls, default to dynamic rendering (#2660)
* force all pages into dynamic rendering, no build-time api calls * allow running docker in production mode * add temporary logging * remove temporary logging * fix typo * remove unnecessary revalidates
1 parent 57787f3 commit 0bbc72b

File tree

6 files changed

+27
-41
lines changed

6 files changed

+27
-41
lines changed

docker-compose.apps.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,13 @@ services:
3636
command:
3737
- |
3838
yarn install --immutable
39-
yarn watch
39+
if [ "$${NODE_ENV}" = "production" ]; then
40+
yarn build
41+
echo "WARNING: Production preview will NOT re-render on file changes."
42+
yarn preview
43+
else
44+
yarn watch
45+
fi
4046
ports:
4147
- "8062:8062"
4248
- "6006:6006"

frontends/main/src/app/layout.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,16 @@ export const metadata = {
1717
metadataBase: NEXT_PUBLIC_ORIGIN ? new URL(NEXT_PUBLIC_ORIGIN) : null,
1818
}
1919

20+
/**
21+
* Force all pages to render dynamically (at request-time) rather than
22+
* statically at build time. This simplifies the build, reduces build time, and
23+
* ensures fresh data on each request to the NextJS server.
24+
*
25+
* It does increase server load, but this should not be significant since
26+
* requests are cached on CDN.
27+
*/
28+
export const dynamic = "force-dynamic"
29+
2030
export default function RootLayout({
2131
children,
2232
}: Readonly<{

frontends/main/src/app/page.tsx

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,6 @@ export async function generateMetadata({
2323
})
2424
}
2525

26-
/**
27-
* Fallback to dynamic rendering to load as much of the page as possible.
28-
*
29-
* We could alternatively wrap the carousels (which use useSearchParams) in a
30-
* suspense boundary. This ostensibly leads to a faster response, since the
31-
* server can render the rest of the homepage at build time.
32-
*
33-
* But... We ache the result on CDN anyway, so it's essentially pre-build for
34-
* most requests, anyway.
35-
*/
36-
export const dynamic = "force-dynamic"
37-
3826
const Page: React.FC<PageProps<"/">> = async () => {
3927
const { dehydratedState } = await prefetch([
4028
// Featured Courses carousel "All"

frontends/main/src/app/search/page.tsx

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,6 @@ export async function generateMetadata({ searchParams }: PageProps<"/search">) {
2020
})
2121
}
2222

23-
/**
24-
* The search page uses Next's `useSearchParams`. This requires either:
25-
* 1. wrap the <SearchPage /> in Suspense
26-
* 2. or force-dynamic.
27-
*
28-
* (1) caused a hydration error for authenticated users. We have not found
29-
* the root cause of the hydration error.
30-
*
31-
* (2) seems to work well.
32-
*/
33-
export const dynamic = "force-dynamic"
34-
3523
const Page: React.FC<PageProps<"/search">> = async ({ searchParams }) => {
3624
const search = (await searchParams) as ResourceSearchRequest & {
3725
page?: string

frontends/main/src/app/sitemaps/channels/sitemap.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,16 @@ invariant(BASE_URL, "NEXT_PUBLIC_ORIGIN must be defined")
1010
const PAGE_SIZE = 100
1111

1212
/**
13-
* By default in NextJS, sitemaps are statically generated at build time.
14-
* We want to ensure up-to-date sitemaps.
15-
*
16-
* This forces the sitemaps to be rendered for each request.
17-
* However, we we set s-maxage in the headers (next.config.js) to enable caching
18-
* by a CDN.
13+
* As of NextJS 15.5.3, sitemaps are ALWAYS generated at build time, even with
14+
* the force-dynamic below (this may be a NextJS bug?). However, the
15+
* force-dynamic does force re-generation when requests are made in production.
1916
*/
2017
export const dynamic = "force-dynamic"
2118

2219
export async function generateSitemaps(): Promise<GenerateSitemapResult[]> {
2320
/**
24-
* NextJS runs this at build time (despite force-dynamic below).
25-
* Early exist here to avoid the useless build-time API calls.
21+
* NextJS runs this at build time (despite force-dynamic above).
22+
* Early exit here to avoid the useless build-time API calls.
2623
*/
2724
if (dangerouslyDetectProductionBuildPhase()) return []
2825
const { count } = (await channelsApi.channelsList({ limit: PAGE_SIZE })).data

frontends/main/src/app/sitemaps/resources/sitemap.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,16 @@ invariant(BASE_URL, "NEXT_PUBLIC_ORIGIN must be defined")
1010
const PAGE_SIZE = 1_000
1111

1212
/**
13-
* By default in NextJS, sitemaps are statically generated at build time.
14-
* We want to ensure up-to-date sitemaps.
15-
*
16-
* This forces the sitemaps to be rendered for each request.
17-
* However, we we set s-maxage in the headers (next.config.js) to enable caching
18-
* by a CDN.
13+
* As of NextJS 15.5.3, sitemaps are ALWAYS generated at build time, even with
14+
* the force-dynamic below (this may be a NextJS bug?). However, the
15+
* force-dynamic does force re-generation when requests are made in production.
1916
*/
2017
export const dynamic = "force-dynamic"
2118

2219
export async function generateSitemaps(): Promise<GenerateSitemapResult[]> {
2320
/**
24-
* NextJS runs this at build time (despite force-dynamic below).
25-
* Early exist here to avoid the useless build-time API calls.
21+
* NextJS runs this at build time (despite force-dynamic above).
22+
* Early exit here to avoid the useless build-time API calls.
2623
*/
2724
if (dangerouslyDetectProductionBuildPhase()) return []
2825
const { count } = (

0 commit comments

Comments
 (0)