From 131502da488cd4c46714e4e424ed2200231cc63e Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Sun, 25 Oct 2020 00:24:14 -0500 Subject: [PATCH 1/2] Expose global defaultLocale in getStaticProps/getStaticPaths --- packages/next/build/utils.ts | 2 +- packages/next/next-server/server/render.tsx | 2 ++ packages/next/types/index.d.ts | 3 +++ .../integration/i18n-support/pages/another.js | 3 ++- .../i18n-support/pages/gsp/fallback/[slug].js | 9 +++++++-- .../i18n-support/pages/gsp/index.js | 3 ++- .../pages/gsp/no-fallback/[slug].js | 3 ++- .../i18n-support/pages/gssp/[slug].js | 8 +++++++- .../i18n-support/pages/gssp/index.js | 3 ++- test/integration/i18n-support/pages/index.js | 3 ++- .../i18n-support/test/index.test.js | 19 +++++++++++++++++++ 11 files changed, 49 insertions(+), 9 deletions(-) diff --git a/packages/next/build/utils.ts b/packages/next/build/utils.ts index 9216875d7e9806c..e6ad2c1e7103a4f 100644 --- a/packages/next/build/utils.ts +++ b/packages/next/build/utils.ts @@ -544,7 +544,7 @@ export async function buildStaticPaths( // Get the default list of allowed params. const _validParamKeys = Object.keys(_routeMatcher(page)) - const staticPathsResult = await getStaticPaths({ locales }) + const staticPathsResult = await getStaticPaths({ locales, defaultLocale }) const expectedReturnVal = `Expected: { paths: [], fallback: boolean }\n` + diff --git a/packages/next/next-server/server/render.tsx b/packages/next/next-server/server/render.tsx index 1cd05e6b21823bf..71a53c66d111ee4 100644 --- a/packages/next/next-server/server/render.tsx +++ b/packages/next/next-server/server/render.tsx @@ -606,6 +606,7 @@ export async function renderToHTML( : undefined), locales: renderOpts.locales, locale: renderOpts.locale, + defaultLocale: renderOpts.defaultLocale, }) } catch (staticPropsError) { // remove not found error code to prevent triggering legacy @@ -738,6 +739,7 @@ export async function renderToHTML( : undefined), locales: renderOpts.locales, locale: renderOpts.locale, + defaultLocale: renderOpts.defaultLocale, }) } catch (serverSidePropsError) { // remove not found error code to prevent triggering legacy diff --git a/packages/next/types/index.d.ts b/packages/next/types/index.d.ts index 1f10532657a9764..d55380171625319 100644 --- a/packages/next/types/index.d.ts +++ b/packages/next/types/index.d.ts @@ -83,6 +83,7 @@ export type GetStaticPropsContext = { previewData?: any locale?: string locales?: string[] + defaultLocale?: string } export type GetStaticPropsResult

= { @@ -107,6 +108,7 @@ export type InferGetStaticPropsType = T extends GetStaticProps export type GetStaticPathsContext = { locales?: string[] + defaultLocale?: string } export type GetStaticPathsResult

= { @@ -130,6 +132,7 @@ export type GetServerSidePropsContext< resolvedUrl: string locale?: string locales?: string[] + defaultLocale?: string } export type GetServerSidePropsResult

= { diff --git a/test/integration/i18n-support/pages/another.js b/test/integration/i18n-support/pages/another.js index 0713a50be1bbb2c..d7d1febc4958046 100644 --- a/test/integration/i18n-support/pages/another.js +++ b/test/integration/i18n-support/pages/another.js @@ -21,11 +21,12 @@ export default function Page(props) { ) } -export const getServerSideProps = ({ locale, locales }) => { +export const getServerSideProps = ({ locale, locales, defaultLocale }) => { return { props: { locale, locales, + defaultLocale, }, } } diff --git a/test/integration/i18n-support/pages/gsp/fallback/[slug].js b/test/integration/i18n-support/pages/gsp/fallback/[slug].js index d4486b24493b382..d0f6e9150391287 100644 --- a/test/integration/i18n-support/pages/gsp/fallback/[slug].js +++ b/test/integration/i18n-support/pages/gsp/fallback/[slug].js @@ -23,17 +23,18 @@ export default function Page(props) { ) } -export const getStaticProps = ({ params, locale, locales }) => { +export const getStaticProps = ({ params, locale, locales, defaultLocale }) => { return { props: { params, locale, locales, + defaultLocale, }, } } -export const getStaticPaths = ({ locales }) => { +export const getStaticPaths = ({ locales, defaultLocale }) => { // make sure locales were provided correctly if (!locales || locales.length !== 7) { throw new Error( @@ -41,6 +42,10 @@ export const getStaticPaths = ({ locales }) => { ) } + if (!defaultLocale) { + throw new Error('missing defaultLocale in getStaticPaths') + } + return { // the default locale will be used since one isn't defined here paths: ['first', 'second'].map((slug) => ({ diff --git a/test/integration/i18n-support/pages/gsp/index.js b/test/integration/i18n-support/pages/gsp/index.js index 7bb55bb36ccd547..574c79399778f81 100644 --- a/test/integration/i18n-support/pages/gsp/index.js +++ b/test/integration/i18n-support/pages/gsp/index.js @@ -21,11 +21,12 @@ export default function Page(props) { ) } -export const getStaticProps = ({ locale, locales }) => { +export const getStaticProps = ({ locale, locales, defaultLocale }) => { return { props: { locale, locales, + defaultLocale, }, } } diff --git a/test/integration/i18n-support/pages/gsp/no-fallback/[slug].js b/test/integration/i18n-support/pages/gsp/no-fallback/[slug].js index 2df6728803f7a2d..a97bd749443a14c 100644 --- a/test/integration/i18n-support/pages/gsp/no-fallback/[slug].js +++ b/test/integration/i18n-support/pages/gsp/no-fallback/[slug].js @@ -23,12 +23,13 @@ export default function Page(props) { ) } -export const getStaticProps = ({ params, locale, locales }) => { +export const getStaticProps = ({ params, locale, locales, defaultLocale }) => { return { props: { params, locale, locales, + defaultLocale, }, } } diff --git a/test/integration/i18n-support/pages/gssp/[slug].js b/test/integration/i18n-support/pages/gssp/[slug].js index 759937cc84c8eab..8b768b0ac56ba25 100644 --- a/test/integration/i18n-support/pages/gssp/[slug].js +++ b/test/integration/i18n-support/pages/gssp/[slug].js @@ -21,12 +21,18 @@ export default function Page(props) { ) } -export const getServerSideProps = ({ params, locale, locales }) => { +export const getServerSideProps = ({ + params, + locale, + locales, + defaultLocale, +}) => { return { props: { params, locale, locales, + defaultLocale, }, } } diff --git a/test/integration/i18n-support/pages/gssp/index.js b/test/integration/i18n-support/pages/gssp/index.js index 6919f3548f7cbd2..eb21a085c24c30f 100644 --- a/test/integration/i18n-support/pages/gssp/index.js +++ b/test/integration/i18n-support/pages/gssp/index.js @@ -21,11 +21,12 @@ export default function Page(props) { ) } -export const getServerSideProps = ({ locale, locales }) => { +export const getServerSideProps = ({ locale, locales, defaultLocale }) => { return { props: { locale, locales, + defaultLocale, }, } } diff --git a/test/integration/i18n-support/pages/index.js b/test/integration/i18n-support/pages/index.js index ce44ddab7b858b1..345e004151c9f5e 100644 --- a/test/integration/i18n-support/pages/index.js +++ b/test/integration/i18n-support/pages/index.js @@ -45,11 +45,12 @@ export default function Page(props) { ) } -export const getStaticProps = ({ locale, locales }) => { +export const getStaticProps = ({ locale, locales, defaultLocale }) => { return { props: { locale, locales, + defaultLocale, }, } } diff --git a/test/integration/i18n-support/test/index.test.js b/test/integration/i18n-support/test/index.test.js index 1074df759376555..b756e275b180f07 100644 --- a/test/integration/i18n-support/test/index.test.js +++ b/test/integration/i18n-support/test/index.test.js @@ -917,6 +917,7 @@ function runTests(isDev) { expect(JSON.parse($('#props').text())).toEqual({ locale: 'en-US', locales, + defaultLocale: 'en-US', }) expect($('#router-locale').text()).toBe('en-US') expect(JSON.parse($('#router-locales').text())).toEqual(locales) @@ -933,6 +934,7 @@ function runTests(isDev) { params: { slug: 'first', }, + defaultLocale: 'en-US', }) expect(JSON.parse($('#router-query').text())).toEqual({ slug: 'first', @@ -953,6 +955,7 @@ function runTests(isDev) { params: { slug: 'another', }, + defaultLocale: 'en-US', }) expect( JSON.parse(await browser.elementByCss('#router-query').text()) @@ -1039,6 +1042,7 @@ function runTests(isDev) { expect(JSON.parse($('#props').text())).toEqual({ locale: 'en-US', locales, + defaultLocale: 'en-US', }) expect($('#router-locale').text()).toBe('en-US') expect(JSON.parse($('#router-locales').text())).toEqual(locales) @@ -1055,6 +1059,7 @@ function runTests(isDev) { params: { slug: 'first', }, + defaultLocale: 'en-US', }) expect(JSON.parse($('#router-query').text())).toEqual({ slug: 'first', @@ -1075,6 +1080,7 @@ function runTests(isDev) { params: { slug: 'another', }, + defaultLocale: 'en-US', }) expect( JSON.parse(await browser.elementByCss('#router-query').text()) @@ -1096,6 +1102,7 @@ function runTests(isDev) { expect(JSON.parse($('#props').text())).toEqual({ locale: 'en-US', locales, + defaultLocale: 'en-US', }) expect($('#router-locale').text()).toBe('en-US') expect(JSON.parse($('#router-locales').text())).toEqual(locales) @@ -1130,6 +1137,7 @@ function runTests(isDev) { expect(JSON.parse(await browser.elementByCss('#props').text())).toEqual({ locale: 'en-US', locales, + defaultLocale: 'en-US', }) expect(await browser.elementByCss('#router-locale').text()).toBe('en-US') expect( @@ -1159,6 +1167,7 @@ function runTests(isDev) { expect(JSON.parse(await browser.elementByCss('#props').text())).toEqual({ locale: 'en-US', locales, + defaultLocale: 'en-US', }) expect(await browser.elementByCss('#router-locale').text()).toBe('en-US') expect( @@ -1192,6 +1201,7 @@ function runTests(isDev) { params: { slug: 'another', }, + defaultLocale: 'en-US', }) expect( JSON.parse(await browser.elementByCss('#router-query').text()) @@ -1215,6 +1225,7 @@ function runTests(isDev) { params: { slug: 'first', }, + defaultLocale: 'en-US', }) expect( JSON.parse(await browser.elementByCss('#router-query').text()) @@ -1241,6 +1252,7 @@ function runTests(isDev) { params: { slug: 'second', }, + defaultLocale: 'en-US', }) expect( JSON.parse(await browser.elementByCss('#router-query').text()) @@ -1275,6 +1287,7 @@ function runTests(isDev) { params: { slug: 'second', }, + defaultLocale: 'en-US', }) expect(JSON.parse($('#router-query').text())).toEqual({ slug: 'second', @@ -1291,6 +1304,7 @@ function runTests(isDev) { expect(JSON.parse($('#props').text())).toEqual({ locale: 'en-US', locales, + defaultLocale: 'en-US', }) expect($('#router-locale').text()).toBe('en-US') expect(JSON.parse($('#router-locales').text())).toEqual(locales) @@ -1303,6 +1317,7 @@ function runTests(isDev) { expect(JSON.parse($2('#props').text())).toEqual({ locale: 'nl-NL', locales, + defaultLocale: 'en-US', }) expect($2('#router-locale').text()).toBe('nl-NL') expect(JSON.parse($2('#router-locales').text())).toEqual(locales) @@ -1320,6 +1335,7 @@ function runTests(isDev) { params: { slug: 'first', }, + defaultLocale: 'en-US', }) expect($('#router-locale').text()).toBe('en-US') expect(JSON.parse($('#router-locales').text())).toEqual(locales) @@ -1335,6 +1351,7 @@ function runTests(isDev) { params: { slug: 'first', }, + defaultLocale: 'en-US', }) expect($2('#router-locale').text()).toBe('nl-NL') expect(JSON.parse($2('#router-locales').text())).toEqual(locales) @@ -1365,6 +1382,7 @@ function runTests(isDev) { expect(JSON.parse(await browser.elementByCss('#props').text())).toEqual({ locale: 'en', locales, + defaultLocale: 'en-US', }) expect( JSON.parse(await browser.elementByCss('#router-query').text()) @@ -1393,6 +1411,7 @@ function runTests(isDev) { expect(JSON.parse(await browser.elementByCss('#props').text())).toEqual({ locale: 'en', locales, + defaultLocale: 'en-US', }) expect( JSON.parse(await browser.elementByCss('#router-query').text()) From afdff4448944ce9a8a5aeddd6c4d7f88aa63f864 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Sun, 25 Oct 2020 00:29:16 -0500 Subject: [PATCH 2/2] Update docs --- docs/advanced-features/i18n-routing.md | 2 +- docs/basic-features/data-fetching.md | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/advanced-features/i18n-routing.md b/docs/advanced-features/i18n-routing.md index 367d15586e707c6..f924a1af8e03268 100644 --- a/docs/advanced-features/i18n-routing.md +++ b/docs/advanced-features/i18n-routing.md @@ -137,7 +137,7 @@ You can access the locale information via the Next.js router. For example, using When [pre-rendering](/docs/basic-features/pages#static-generation-recommended) pages with `getStaticProps` or `getServerSideProps`, the locale information is provided in [the context](https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation) provided to the function. -When leveraging `getStaticPaths`, the supported locales are provided in the context parameter of the function under `locales`. +When leveraging `getStaticPaths`, the configured locales are provided in the context parameter of the function under `locales` and the configured defaultLocale under `defaultLocale`. ## Transition between locales diff --git a/docs/basic-features/data-fetching.md b/docs/basic-features/data-fetching.md index 2ca3fe32af60993..7f973189425d812 100644 --- a/docs/basic-features/data-fetching.md +++ b/docs/basic-features/data-fetching.md @@ -56,6 +56,7 @@ The `context` parameter is an object containing the following keys: - `previewData` contains the preview data set by `setPreviewData`. See the [Preview Mode documentation](/docs/advanced-features/preview-mode.md). - `locale` contains the active locale (if enabled). - `locales` contains all supported locales (if enabled). +- `defaultLocale` contains the configured default locale (if enabled). `getStaticProps` should return an object with: @@ -547,6 +548,9 @@ The `context` parameter is an object containing the following keys: - `preview`: `preview` is `true` if the page is in the preview mode and `false` otherwise. See the [Preview Mode documentation](/docs/advanced-features/preview-mode.md). - `previewData`: The preview data set by `setPreviewData`. See the [Preview Mode documentation](/docs/advanced-features/preview-mode.md). - `resolvedUrl`: A normalized version of the request URL that strips the `_next/data` prefix for client transitions and includes original query values. +- `locale` contains the active locale (if enabled). +- `locales` contains all supported locales (if enabled). +- `defaultLocale` contains the configured default locale (if enabled). > **Note**: You can import modules in top-level scope for use in `getServerSideProps`. > Imports used in `getServerSideProps` will not be bundled for the client-side.