Skip to content

Commit 02f5a3e

Browse files
authored
CI: Static export locale (#7409)
* ci: static export locale * refactor: updated logic in conditions
1 parent 1e4fc38 commit 02f5a3e

File tree

6 files changed

+94
-25
lines changed

6 files changed

+94
-25
lines changed

.github/workflows/build.yml

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,29 @@ jobs:
114114
# Used for API requests that require GitHub API scopes
115115
NEXT_GITHUB_API_KEY: ${{ secrets.GITHUB_TOKEN }}
116116

117-
- name: Build Next.js (Static)
118-
# We only run full static builds within Pull Requests. As they're not needed on `merge_group` or `push` events
117+
- name: Build Next.js (Static All Locales)
118+
# We only run full static builds within Pull Requests. This step is also used to export
119+
# static output in all languages, and it only works on `push` events.
120+
if: github.event_name == 'push'
121+
# We want to enforce that the actual `turbo@latest` package is used instead of a possible hijack from the user
122+
# the `${{ steps.turborepo_arguments.outputs.turbo_args }}` is a string substitution coming from a previous step
123+
run: npx --package=turbo@latest -- turbo deploy ${{ steps.turborepo_arguments.outputs.turbo_args }}
124+
env:
125+
# We want to ensure we have enough RAM allocated to the Node.js process
126+
# this should be a last resort in case by any chances the build memory gets too high
127+
# but in general this should never happen
128+
NODE_OPTIONS: '--max_old_space_size=4096'
129+
# Used for API requests that require GitHub API scopes
130+
NEXT_GITHUB_API_KEY: ${{ secrets.GITHUB_TOKEN }}
131+
# We want to ensure that static exports for all locales are triggered only on `push` events to save resources
132+
# and time.
133+
NEXT_PUBLIC_STATIC_EXPORT_LOCALE: true
134+
135+
- name: Build Next.js (Static Default Locale)
136+
# We want to generate static output in the default language within Pull Requests
137+
# in order to reduce source wastages and build times.
119138
# Note that we skip full static builds on Crowdin-based Pull Requests as these PRs should only contain translation changes
120139
if: |
121-
(github.event_name == 'push') ||
122140
(github.event_name == 'pull_request_target' &&
123141
github.event.pull_request.head.ref != 'chore/crowdin')
124142
# We want to enforce that the actual `turbo@latest` package is used instead of a possible hijack from the user
@@ -131,6 +149,8 @@ jobs:
131149
NODE_OPTIONS: '--max_old_space_size=4096'
132150
# Used for API requests that require GitHub API scopes
133151
NEXT_GITHUB_API_KEY: ${{ secrets.GITHUB_TOKEN }}
152+
# We want to ensure that static exports for all locales do not occur on `pull_request_target` events
153+
NEXT_PUBLIC_STATIC_EXPORT_LOCALE: false
134154

135155
- name: Sync Orama Cloud
136156
# We only want to sync the Orama Cloud production indexes on `push` events.

apps/site/app/[locale]/[...path]/page.tsx

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@
88
*/
99

1010
import * as basePage from '@/app/[locale]/page';
11-
import { ENABLE_STATIC_EXPORT } from '@/next.constants.mjs';
11+
import {
12+
ENABLE_STATIC_EXPORT_LOCALE,
13+
ENABLE_STATIC_EXPORT,
14+
} from '@/next.constants.mjs';
1215
import { dynamicRouter } from '@/next.dynamic.mjs';
13-
import { availableLocaleCodes } from '@/next.locales.mjs';
16+
import { availableLocaleCodes, defaultLocale } from '@/next.locales.mjs';
1417

1518
// This is the default Viewport Metadata
1619
// @see https://nextjs.org/docs/app/api-reference/functions/generate-viewport#generateviewport-function
@@ -20,21 +23,35 @@ export const generateViewport = basePage.generateViewport;
2023
// @see https://nextjs.org/docs/app/api-reference/functions/generate-metadata
2124
export const generateMetadata = basePage.generateMetadata;
2225

23-
// This provides all the possible paths that can be generated statically
24-
// + provides all the paths that we support on the Node.js Website
26+
// Generates all possible static paths based on the locales and environment configuration
27+
// - Returns an empty array if static export is disabled (`ENABLE_STATIC_EXPORT` is false)
28+
// - If `ENABLE_STATIC_EXPORT_LOCALE` is true, generates paths for all available locales
29+
// - Otherwise, generates paths only for the default locale
30+
// @see https://nextjs.org/docs/app/api-reference/functions/generate-static-params
2531
export const generateStaticParams = async () => {
26-
const allAvailableRoutes = await Promise.all(
27-
// Gets all mapped routes to the Next.js Routing Engine by Locale
28-
availableLocaleCodes.map(async (locale: string) => {
29-
const routesForLanguage = await dynamicRouter.getRoutesByLanguage(locale);
30-
31-
return routesForLanguage.map(pathname =>
32-
dynamicRouter.mapPathToRoute(locale, pathname)
33-
);
34-
})
35-
);
36-
37-
return ENABLE_STATIC_EXPORT ? allAvailableRoutes.flat().sort() : [];
32+
// Return an empty array if static export is disabled
33+
if (!ENABLE_STATIC_EXPORT) {
34+
return [];
35+
}
36+
37+
// Helper function to fetch and map routes for a specific locale
38+
const getRoutesForLocale = async (locale: string) => {
39+
const routes = await dynamicRouter.getRoutesByLanguage(locale);
40+
41+
return routes.map(pathname =>
42+
dynamicRouter.mapPathToRoute(locale, pathname)
43+
);
44+
};
45+
46+
// Determine which locales to include in the static export
47+
const locales = ENABLE_STATIC_EXPORT_LOCALE
48+
? availableLocaleCodes
49+
: [defaultLocale.code];
50+
51+
// Generates all possible routes for all available locales
52+
const routes = await Promise.all(locales.map(getRoutesForLocale));
53+
54+
return routes.flat().sort();
3855
};
3956

4057
// Enforces that this route is used as static rendering

apps/site/app/[locale]/page.tsx

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ import type { FC } from 'react';
1313

1414
import { setClientContext } from '@/client-context';
1515
import WithLayout from '@/components/withLayout';
16-
import { ENABLE_STATIC_EXPORT } from '@/next.constants.mjs';
16+
import {
17+
ENABLE_STATIC_EXPORT_LOCALE,
18+
ENABLE_STATIC_EXPORT,
19+
} from '@/next.constants.mjs';
1720
import { PAGE_VIEWPORT, DYNAMIC_ROUTES } from '@/next.dynamic.constants.mjs';
1821
import { dynamicRouter } from '@/next.dynamic.mjs';
1922
import { allLocaleCodes, availableLocaleCodes } from '@/next.locales.mjs';
@@ -37,15 +40,28 @@ export const generateMetadata = async (props: DynamicParams) => {
3740
return dynamicRouter.getPageMetadata(locale, pathname);
3841
};
3942

40-
// This provides all the possible paths that can be generated statically
41-
// + provides all the paths that we support on the Node.js Website
43+
// Generates all possible static paths based on the locales and environment configuration
44+
// - Returns an empty array if static export is disabled (`ENABLE_STATIC_EXPORT` is false)
45+
// - If `ENABLE_STATIC_EXPORT_LOCALE` is true, generates paths for all available locales
46+
// - Otherwise, generates paths only for the default locale
47+
// @see https://nextjs.org/docs/app/api-reference/functions/generate-static-params
4248
export const generateStaticParams = async () => {
43-
const allAvailableRoutes = await Promise.all(
49+
// Return an empty array if static export is disabled
50+
if (!ENABLE_STATIC_EXPORT) {
51+
return [];
52+
}
53+
54+
// Determine which locales to include in the static export
55+
const locales = ENABLE_STATIC_EXPORT_LOCALE
56+
? availableLocaleCodes
57+
: [defaultLocale.code];
58+
59+
const routes = await Promise.all(
4460
// Gets all mapped routes to the Next.js Routing Engine by Locale
45-
availableLocaleCodes.map((locale: string) => ({ locale }))
61+
locales.map((locale: string) => ({ locale }))
4662
);
4763

48-
return ENABLE_STATIC_EXPORT ? allAvailableRoutes.flat().sort() : [];
64+
return routes.flat().sort();
4965
};
5066

5167
// This method parses the current pathname and does any sort of modifications needed on the route

apps/site/next.constants.mjs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,17 @@ export const ENABLE_STATIC_EXPORT =
3535
process.env.NEXT_PUBLIC_STATIC_EXPORT === 'true' ||
3636
process.env.NEXT_PUBLIC_STATIC_EXPORT === true;
3737

38+
/**
39+
* This is used to ensure that pages are Static Export for all locales or only
40+
* in the default (`en`) locale.
41+
*
42+
* Note that this is a manual Environment Variable defined by us during the
43+
* build process in CI.
44+
*/
45+
export const ENABLE_STATIC_EXPORT_LOCALE =
46+
process.env.NEXT_PUBLIC_STATIC_EXPORT_LOCALE === 'true' ||
47+
process.env.NEXT_PUBLIC_STATIC_EXPORT_LOCALE === true;
48+
3849
/**
3950
* This is used for any place that requires the full canonical URL path for the Node.js Website (and its deployment), such as for example, the Node.js RSS Feed.
4051
*

apps/site/turbo.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"VERCEL_URL",
1212
"VERCEL_REGION",
1313
"NEXT_PUBLIC_STATIC_EXPORT",
14+
"NEXT_PUBLIC_STATIC_EXPORT_LOCALE",
1415
"NEXT_PUBLIC_BASE_URL",
1516
"NEXT_PUBLIC_DIST_URL",
1617
"NEXT_PUBLIC_DOCS_URL",
@@ -37,6 +38,7 @@
3738
"VERCEL_URL",
3839
"VERCEL_REGION",
3940
"NEXT_PUBLIC_STATIC_EXPORT",
41+
"NEXT_PUBLIC_STATIC_EXPORT_LOCALE",
4042
"NEXT_PUBLIC_BASE_URL",
4143
"NEXT_PUBLIC_DIST_URL",
4244
"NEXT_PUBLIC_DOCS_URL",
@@ -56,6 +58,7 @@
5658
"VERCEL_URL",
5759
"VERCEL_REGION",
5860
"NEXT_PUBLIC_STATIC_EXPORT",
61+
"NEXT_PUBLIC_STATIC_EXPORT_LOCALE",
5962
"NEXT_PUBLIC_BASE_URL",
6063
"NEXT_PUBLIC_DIST_URL",
6164
"NEXT_PUBLIC_DOCS_URL",
@@ -81,6 +84,7 @@
8184
"VERCEL_URL",
8285
"VERCEL_REGION",
8386
"NEXT_PUBLIC_STATIC_EXPORT",
87+
"NEXT_PUBLIC_STATIC_EXPORT_LOCALE",
8488
"NEXT_PUBLIC_BASE_URL",
8589
"NEXT_PUBLIC_DIST_URL",
8690
"NEXT_PUBLIC_DOCS_URL",

packages/i18n/turbo.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"VERCEL_URL",
1515
"VERCEL_REGION",
1616
"NEXT_PUBLIC_STATIC_EXPORT",
17+
"NEXT_PUBLIC_STATIC_EXPORT_LOCALE",
1718
"NEXT_PUBLIC_BASE_URL",
1819
"NEXT_PUBLIC_DIST_URL",
1920
"NEXT_PUBLIC_DOCS_URL",

0 commit comments

Comments
 (0)