From 0ff0e5e9e8f4184fa42b2bf1fe65e6df1125333e Mon Sep 17 00:00:00 2001 From: Vadorequest Date: Sat, 29 May 2021 00:24:41 +0200 Subject: [PATCH] Fix 404 page generation + refactor all layouts SSG/SSR (gcms preset) (#347) --- src/layouts/core/coreLayoutSSG.ts | 261 +++++++++-------- src/layouts/core/coreLayoutSSR.ts | 179 ++++++------ .../types/GetCoreLayoutServerSideProps.ts | 23 ++ .../core/types/GetCoreLayoutStaticPaths.ts | 25 ++ .../core/types/GetCoreLayoutStaticProps.ts | 26 ++ src/layouts/demo/demoLayoutSSG.ts | 263 ++++++++++-------- src/layouts/demo/demoLayoutSSR.ts | 177 ++++++------ .../types/GetDemoLayoutServerSideProps.ts | 17 ++ .../demo/types/GetDemoLayoutStaticPaths.ts | 16 ++ .../demo/types/GetDemoLayoutStaticProps.ts | 20 ++ src/layouts/public/pagePublicTemplateSSG.tsx | 4 +- src/layouts/public/pagePublicTemplateSSR.tsx | 2 +- src/layouts/public/publicLayoutSSG.ts | 179 +++++++----- src/layouts/public/publicLayoutSSR.ts | 151 +++++----- .../types/GetPublicLayoutServerSideProps.ts | 23 ++ .../types/GetPublicLayoutStaticPaths.ts | 25 ++ .../types/GetPublicLayoutStaticProps.ts | 26 ++ src/pages/404.tsx | 2 +- .../demo/built-in-features/analytics.tsx | 8 +- .../demo/built-in-features/animations.tsx | 8 +- .../built-in-features/cookies-consent.tsx | 8 +- .../demo/built-in-features/css-in-js.tsx | 8 +- .../demo/built-in-features/docs-site.tsx | 8 +- .../demo/built-in-features/graphql.tsx | 8 +- .../demo/built-in-features/hosting.tsx | 8 +- .../[locale]/demo/built-in-features/icons.tsx | 8 +- .../built-in-features/manual-deployments.tsx | 8 +- .../demo/built-in-features/monitoring.tsx | 8 +- .../built-in-features/stages-and-secrets.tsx | 8 +- .../demo/built-in-features/static-i18n.tsx | 8 +- .../demo/built-in-features/ui-components.tsx | 8 +- .../[locale]/demo/built-in-utilities/api.tsx | 8 +- .../built-in-utilities/bundle-analysis.tsx | 8 +- .../built-in-utilities/errors-handling.tsx | 8 +- .../demo/built-in-utilities/hooks.tsx | 8 +- .../built-in-utilities/i18nLink-component.tsx | 8 +- .../built-in-utilities/interactive-error.tsx | 8 +- .../built-in-utilities/packages-upgrade.tsx | 8 +- .../built-in-utilities/security-audit.tsx | 8 +- .../demo/built-in-utilities/svg-to-react.tsx | 8 +- .../top-level-500-error.tsx | 8 +- .../tracking-useless-re-renders.tsx | 8 +- src/pages/[locale]/demo/index.tsx | 8 +- .../[[...slug]].tsx | 4 +- .../[albumId].tsx | 8 +- .../example-with-ssg-and-revalidate.tsx | 8 +- .../demo/native-features/example-with-ssg.tsx | 8 +- .../demo/native-features/example-with-ssr.tsx | 6 +- src/pages/[locale]/demo/privacy.tsx | 8 +- src/pages/[locale]/demo/terms.tsx | 8 +- src/pages/[locale]/public/index.tsx | 4 +- 51 files changed, 1025 insertions(+), 648 deletions(-) create mode 100644 src/layouts/core/types/GetCoreLayoutServerSideProps.ts create mode 100644 src/layouts/core/types/GetCoreLayoutStaticPaths.ts create mode 100644 src/layouts/core/types/GetCoreLayoutStaticProps.ts create mode 100644 src/layouts/demo/types/GetDemoLayoutServerSideProps.ts create mode 100644 src/layouts/demo/types/GetDemoLayoutStaticPaths.ts create mode 100644 src/layouts/demo/types/GetDemoLayoutStaticProps.ts create mode 100644 src/layouts/public/types/GetPublicLayoutServerSideProps.ts create mode 100644 src/layouts/public/types/GetPublicLayoutStaticPaths.ts create mode 100644 src/layouts/public/types/GetPublicLayoutStaticProps.ts diff --git a/src/layouts/core/coreLayoutSSG.ts b/src/layouts/core/coreLayoutSSG.ts index b2f6882e..d4eed2fe 100644 --- a/src/layouts/core/coreLayoutSSG.ts +++ b/src/layouts/core/coreLayoutSSG.ts @@ -3,6 +3,14 @@ import { StaticPath } from '@/app/types/StaticPath'; import { StaticPathsOutput } from '@/app/types/StaticPathsOutput'; import { StaticPropsInput } from '@/app/types/StaticPropsInput'; import { DEMO_LAYOUT_QUERY } from '@/common/gql/demoLayoutQuery'; +import { + GetCoreLayoutStaticPaths, + GetCoreLayoutStaticPathsOptions, +} from '@/layouts/core/types/GetCoreLayoutStaticPaths'; +import { + GetCoreLayoutStaticProps, + GetCoreLayoutStaticPropsOptions, +} from '@/layouts/core/types/GetCoreLayoutStaticProps'; import { SSGPageProps } from '@/layouts/core/types/SSGPageProps'; import { APOLLO_STATE_PROP_NAME, @@ -40,143 +48,170 @@ import { GetStaticPropsResult, } from 'next'; -const fileLabel = 'layouts/demo/demoLayoutSSG'; +const fileLabel = 'layouts/core/coreLayoutSSG'; const logger = createLogger({ fileLabel, }); /** - * Only executed on the server side at build time. - * Computes all static paths that should be available for all SSG pages. - * Necessary when a page has dynamic routes and uses "getStaticProps", in order to build the HTML pages. - * - * You can use "fallback" option to avoid building all page variants and allow runtime fallback. - * - * Meant to avoid code duplication between pages sharing the same layout. - * Can be overridden for per-page customisation (e.g: deepmerge). - * - * XXX Core component, meant to be used by other layouts, shouldn't be used by other components directly. + * Returns a "getStaticPaths" function. * - * @return Static paths that will be used by "getCoreStaticProps" to generate pages - * - * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticpaths-static-generation + * @param options */ -export const getCoreStaticPaths: GetStaticPaths = async (context: GetStaticPathsContext): Promise => { - const lang = DEFAULT_LOCALE; - const bestCountryCodes: string[] = [lang, resolveFallbackLanguage(lang)]; - const gcmsLocales: string = prepareGraphCMSLocaleHeader(bestCountryCodes); - const dataset: StaticDataset | GraphCMSDataset = await getGraphcmsDataset(gcmsLocales); - const customer: StaticCustomer | Customer = dataset?.customer; +export const getCoreLayoutStaticPaths: GetCoreLayoutStaticPaths = (options?: GetCoreLayoutStaticPathsOptions) => { + const { + fallback = false, + } = options || {}; + + /** + * Only executed on the server side at build time. + * Computes all static paths that should be available for all SSG pages. + * Necessary when a page has dynamic routes and uses "getStaticProps", in order to build the HTML pages. + * + * You can use "fallback" option to avoid building all page variants and allow runtime fallback. + * + * Meant to avoid code duplication between pages sharing the same layout. + * Can be overridden for per-page customisation (e.g: deepmerge). + * + * XXX Core component, meant to be used by other layouts, shouldn't be used by other components directly. + * + * @return Static paths that will be used by "getCoreLayoutStaticProps" to generate pages + * + * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticpaths-static-generation + */ + const getStaticPaths: GetStaticPaths = async (context: GetStaticPathsContext): Promise => { + const lang = DEFAULT_LOCALE; + const bestCountryCodes: string[] = [lang, resolveFallbackLanguage(lang)]; + const gcmsLocales: string = prepareGraphCMSLocaleHeader(bestCountryCodes); + const dataset: StaticDataset | GraphCMSDataset = await getGraphcmsDataset(gcmsLocales); + const customer: StaticCustomer | Customer = dataset?.customer; + + // Generate only pages for languages that have been allowed by the customer + const paths: StaticPath[] = map(customer?.availableLanguages, (availableLanguage: string): StaticPath => { + return { + params: { + locale: availableLanguage, + }, + }; + }); - // Generate only pages for languages that have been allowed by the customer - const paths: StaticPath[] = map(customer?.availableLanguages, (availableLanguage: string): StaticPath => { return { - params: { - locale: availableLanguage, - }, + fallback, + paths, }; - }); - - return { - fallback: false, - paths, }; + + return getStaticPaths; }; /** - * Only executed on the server side at build time. - * Computes all static props that should be available for all SSG pages. - * - * Note that when a page uses "getStaticProps", then "_app:getInitialProps" is executed (if defined) but not actually used by the page, - * only the results from getStaticProps are actually injected into the page (as "SSGPageProps"). - * - * Meant to avoid code duplication between pages sharing the same layout. - * Can be overridden for per-page customisation (e.g: deepmerge). + * Returns a "getStaticProps" function. * - * XXX Core component, meant to be used by other layouts, shouldn't be used by other components directly. + * Disables redirecting to the 404 page when building the 404 page. * - * @return Props (as "SSGPageProps") that will be passed to the Page component, as props (known as "pageProps" in _app). - * - * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 - * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation + * @param options */ -export const getCoreStaticProps: GetStaticProps = async (props: StaticPropsInput): Promise> => { - const customerRef: string = process.env.NEXT_PUBLIC_CUSTOMER_REF; - const preview: boolean = props?.preview || false; - const previewData: PreviewData = props?.previewData || null; - const hasLocaleFromUrl = !!props?.params?.locale; - const locale: string = hasLocaleFromUrl ? props?.params?.locale : DEFAULT_LOCALE; // If the locale isn't found (e.g: 404 page) - const lang: string = locale.split('-')?.[0]; - const bestCountryCodes: string[] = [lang, resolveFallbackLanguage(lang)]; - const gcmsLocales: string = prepareGraphCMSLocaleHeader(bestCountryCodes); - const i18nTranslations: I18nextResources = await getLocizeTranslations(lang); - // XXX This part is not using "getGraphcmsDataset" because I'm not sure how to return the "apolloClient" instance when doing so, as it'll be wrapped and isn't returned - // So, code is duplicated, but that works fine - const apolloClient: ApolloClient = initializeApollo(); - const variables = { - customerRef, - }; - const queryOptions = { - displayName: 'DEMO_LAYOUT_QUERY', - query: DEMO_LAYOUT_QUERY, - variables, - context: { - headers: { - 'gcms-locales': gcmsLocales, +export const getCoreLayoutStaticProps: GetCoreLayoutStaticProps = (options?: GetCoreLayoutStaticPropsOptions): GetStaticProps => { + const { + enable404Redirect = true, + } = options || {}; + + /** + * Only executed on the server side at build time. + * Computes all static props that should be available for all SSG pages. + * + * Note that when a page uses "getStaticProps", then "_app:getInitialProps" is executed (if defined) but not actually used by the page, + * only the results from getStaticProps are actually injected into the page (as "SSGPageProps"). + * + * Meant to avoid code duplication between pages sharing the same layout. + * Can be overridden for per-page customisation (e.g: deepmerge). + * + * XXX Core component, meant to be used by other layouts, shouldn't be used by other components directly. + * + * @return Props (as "SSGPageProps") that will be passed to the Page component, as props (known as "pageProps" in _app). + * + * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 + * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation + */ + const getStaticProps: GetStaticProps = async (props: StaticPropsInput): Promise> => { + const customerRef: string = process.env.NEXT_PUBLIC_CUSTOMER_REF; + const preview: boolean = props?.preview || false; + const previewData: PreviewData = props?.previewData || null; + const hasLocaleFromUrl = !!props?.params?.locale; + const locale: string = hasLocaleFromUrl ? props?.params?.locale : DEFAULT_LOCALE; // If the locale isn't found (e.g: 404 page) + const lang: string = locale.split('-')?.[0]; + const bestCountryCodes: string[] = [lang, resolveFallbackLanguage(lang)]; + const gcmsLocales: string = prepareGraphCMSLocaleHeader(bestCountryCodes); + const i18nTranslations: I18nextResources = await getLocizeTranslations(lang); + // XXX This part is not using "getGraphcmsDataset" because I'm not sure how to return the "apolloClient" instance when doing so, as it'll be wrapped and isn't returned + // So, code is duplicated, but that works fine + const apolloClient: ApolloClient = initializeApollo(); + const variables = { + customerRef, + }; + const queryOptions = { + displayName: 'DEMO_LAYOUT_QUERY', + query: DEMO_LAYOUT_QUERY, + variables, + context: { + headers: { + 'gcms-locales': gcmsLocales, + }, }, - }, - }; + }; - const { - data, - errors, - loading, - networkStatus, - ...rest - }: ApolloQueryResult<{ - customer: Customer; - }> = await apolloClient.query(queryOptions); + const { + data, + errors, + loading, + networkStatus, + ...rest + }: ApolloQueryResult<{ + customer: Customer; + }> = await apolloClient.query(queryOptions); - if (errors) { - // eslint-disable-next-line no-console - console.error(errors); - throw new Error('Errors were detected in GraphQL query.'); - } + if (errors) { + // eslint-disable-next-line no-console + console.error(errors); + throw new Error('Errors were detected in GraphQL query.'); + } - const { - customer, - } = data || {}; // XXX Use empty object as fallback, to avoid app crash when destructuring, if no data is returned - const dataset = { - customer, - }; + const { + customer, + } = data || {}; // XXX Use empty object as fallback, to avoid app crash when destructuring, if no data is returned + const dataset = { + customer, + }; + + // Do not serve pages using locales the customer doesn't have enabled (useful during preview mode and in development env) + if (enable404Redirect && !includes(customer?.availableLanguages, locale)) { + logger.warn(`Locale "${locale}" not enabled for this customer (allowed: "${customer?.availableLanguages}"), returning 404 page.`); - // Do not serve pages using locales the customer doesn't have enabled (useful during preview mode and in development env) - if (!includes(customer?.availableLanguages, locale)) { - logger.warn(`Locale "${locale}" not enabled for this customer (allowed: "${customer?.availableLanguages}"), returning 404 page.`); + return { + notFound: true, + }; + } return { - notFound: true, + // Props returned here will be available as page properties (pageProps) + props: { + [APOLLO_STATE_PROP_NAME]: getApolloState(apolloClient), + bestCountryCodes, + serializedDataset: serializeSafe(dataset), + customer, + customerRef, + i18nTranslations, + gcmsLocales, + hasLocaleFromUrl, + isReadyToRender: true, + isStaticRendering: true, + lang, + locale, + preview, + previewData, + }, }; - } - - return { - // Props returned here will be available as page properties (pageProps) - props: { - [APOLLO_STATE_PROP_NAME]: getApolloState(apolloClient), - bestCountryCodes, - serializedDataset: serializeSafe(dataset), - customer, - customerRef, - i18nTranslations, - gcmsLocales, - hasLocaleFromUrl, - isReadyToRender: true, - isStaticRendering: true, - lang, - locale, - preview, - previewData, - }, }; -}; + return getStaticProps; +}; diff --git a/src/layouts/core/coreLayoutSSR.ts b/src/layouts/core/coreLayoutSSR.ts index 2dbf7c7d..17e51e63 100644 --- a/src/layouts/core/coreLayoutSSR.ts +++ b/src/layouts/core/coreLayoutSSR.ts @@ -1,5 +1,9 @@ import { CommonServerSideParams } from '@/app/types/CommonServerSideParams'; import { DEMO_LAYOUT_QUERY } from '@/common/gql/demoLayoutQuery'; +import { + GetCoreLayoutServerSideProps, + GetCoreServerSidePropsOptions, +} from '@/layouts/core/types/GetCoreLayoutServerSideProps'; import { PublicHeaders } from '@/layouts/core/types/PublicHeaders'; import { SSRPageProps } from '@/layouts/core/types/SSRPageProps'; import { initializeApollo } from '@/modules/core/apollo/apolloClient'; @@ -36,108 +40,123 @@ import { } from 'next'; import NextCookies from 'next-cookies'; -const fileLabel = 'layouts/demo/demoLayoutSSR'; +const fileLabel = 'layouts/core/coreLayoutSSR'; const logger = createLogger({ fileLabel, }); /** - * "getCoreServerSideProps" returns only part of the props expected in SSRPageProps. + * "getCoreLayoutServerSideProps" returns only part of the props expected in SSRPageProps. * To avoid TS errors, we omit those that we don't return, and add those necessary to the "getServerSideProps" function. */ -export type GetCoreServerSidePropsResults = Omit & { +export type GetCoreLayoutServerSidePropsResults = Omit & { apolloClient: ApolloClient; layoutQueryOptions: ApolloQueryOptions; headers: PublicHeaders; } /** - * Only executed on the server side, for every request. - * Computes some dynamic props that should be available for all SSR pages that use getServerSideProps. - * - * Because the exact GQL query will depend on the consumer (AKA "caller"), this helper doesn't run any query by itself, but rather return all necessary props to allow the consumer to perform its own queries. - * This improves performances, by only running one GQL query instead of many (consumer's choice). + * Returns a "getServerSideProps" function. * - * Meant to avoid code duplication between pages sharing the same layout. + * Disables redirecting to the 404 page when building the 404 page. * - * XXX Core component, meant to be used by other layouts, shouldn't be used by other components directly. - * - * @see https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering + * @param options */ -export const getCoreServerSideProps: GetServerSideProps = async (context: GetServerSidePropsContext): Promise> => { +export const getCoreLayoutServerSideProps: GetCoreLayoutServerSideProps = (options?: GetCoreServerSidePropsOptions) => { const { - query, - params, - req, - res, - ...rest - } = context; - const isQuickPreviewPage: boolean = isQuickPreviewRequest(req); - const customerRef: string = process.env.NEXT_PUBLIC_CUSTOMER_REF; - const readonlyCookies: Cookies = NextCookies(context); // Parses Next.js cookies in a universal way (server + client) - const cookiesManager: UniversalCookiesManager = new UniversalCookiesManager(req, res); // Cannot be forwarded as pageProps, because contains circular refs - const userSession: UserSemiPersistentSession = cookiesManager.getUserData(); - const { headers }: IncomingMessage = req; - const publicHeaders: PublicHeaders = { - 'accept-language': headers?.['accept-language'], - 'user-agent': headers?.['user-agent'], - 'host': headers?.host, - }; - const hasLocaleFromUrl = !!query?.locale; - const locale: string = resolveSSRLocale(query, req, readonlyCookies); - const lang: string = locale.split('-')?.[0]; - const bestCountryCodes: string[] = [lang, resolveFallbackLanguage(lang)]; - const gcmsLocales: string = prepareGraphCMSLocaleHeader(bestCountryCodes); - const i18nTranslations: I18nextResources = await getLocizeTranslations(lang); - // XXX This part is not using "getGraphcmsDataset" because I'm not sure how to return the "apolloClient" instance when doing so, as it'll be wrapped and isn't returned - // So, code is duplicated, but that works fine - const apolloClient: ApolloClient = initializeApollo(); - const variables = { - customerRef, - }; - const layoutQueryOptions: ApolloQueryOptions = { - displayName: 'DEMO_LAYOUT_QUERY', - query: DEMO_LAYOUT_QUERY, - variables, - context: { - headers: { - 'gcms-locales': gcmsLocales, + enable404Redirect = true, + } = options || {}; + + /** + * Only executed on the server side, for every request. + * Computes some dynamic props that should be available for all SSR pages that use getServerSideProps. + * + * Because the exact GQL query will depend on the consumer (AKA "caller"), this helper doesn't run any query by itself, but rather return all necessary props to allow the consumer to perform its own queries. + * This improves performances, by only running one GQL query instead of many (consumer's choice). + * + * Meant to avoid code duplication between pages sharing the same layout. + * + * XXX Core component, meant to be used by other layouts, shouldn't be used by other components directly. + * + * @see https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering + */ + const getServerSideProps: GetServerSideProps = async (context: GetServerSidePropsContext): Promise> => { + const { + query, + params, + req, + res, + ...rest + } = context; + const isQuickPreviewPage: boolean = isQuickPreviewRequest(req); + const customerRef: string = process.env.NEXT_PUBLIC_CUSTOMER_REF; + const readonlyCookies: Cookies = NextCookies(context); // Parses Next.js cookies in a universal way (server + client) + const cookiesManager: UniversalCookiesManager = new UniversalCookiesManager(req, res); // Cannot be forwarded as pageProps, because contains circular refs + const userSession: UserSemiPersistentSession = cookiesManager.getUserData(); + const { headers }: IncomingMessage = req; + const publicHeaders: PublicHeaders = { + 'accept-language': headers?.['accept-language'], + 'user-agent': headers?.['user-agent'], + 'host': headers?.host, + }; + const hasLocaleFromUrl = !!query?.locale; + const locale: string = resolveSSRLocale(query, req, readonlyCookies); + const lang: string = locale.split('-')?.[0]; + const bestCountryCodes: string[] = [lang, resolveFallbackLanguage(lang)]; + const gcmsLocales: string = prepareGraphCMSLocaleHeader(bestCountryCodes); + const i18nTranslations: I18nextResources = await getLocizeTranslations(lang); + // XXX This part is not using "getGraphcmsDataset" because I'm not sure how to return the "apolloClient" instance when doing so, as it'll be wrapped and isn't returned + // So, code is duplicated, but that works fine + const apolloClient: ApolloClient = initializeApollo(); + const variables = { + customerRef, + }; + const layoutQueryOptions: ApolloQueryOptions = { + displayName: 'DEMO_LAYOUT_QUERY', + query: DEMO_LAYOUT_QUERY, + variables, + context: { + headers: { + 'gcms-locales': gcmsLocales, + }, }, - }, - }; + }; + + const dataset: StaticDataset | GraphCMSDataset = await getGraphcmsDataset(gcmsLocales); + const customer: StaticCustomer | Customer = dataset?.customer; - const dataset: StaticDataset | GraphCMSDataset = await getGraphcmsDataset(gcmsLocales); - const customer: StaticCustomer | Customer = dataset?.customer; + // Do not serve pages using locales the customer doesn't have enabled + if (enable404Redirect && !includes(customer?.availableLanguages, locale)) { + logger.warn(`Locale "${locale}" not enabled for this customer (allowed: "${customer?.availableLanguages}"), returning 404 page.`); - // Do not serve pages using locales the customer doesn't have enabled - if (!includes(customer?.availableLanguages, locale)) { - logger.warn(`Locale "${locale}" not enabled for this customer (allowed: "${customer?.availableLanguages}"), returning 404 page.`); + return { + notFound: true, + }; + } + // Most props returned here will be necessary for the app to work properly (see "SSRPageProps") + // Some props are meant to be helpful to the consumer and won't be passed down to the _app.render (e.g: apolloClient, layoutQueryOptions) return { - notFound: true, + props: { + apolloClient, + bestCountryCodes, + serializedDataset: null, // We don't send the dataset yet (we don't have any because we haven't fetched the database yet), but it must be done by SSR pages in"getServerSideProps" + customerRef, + i18nTranslations, + headers: publicHeaders, + gcmsLocales, + hasLocaleFromUrl, + isReadyToRender: true, + isServerRendering: true, + lang, + locale, + layoutQueryOptions, + readonlyCookies, + userSession, + isQuickPreviewPage, + }, }; - } - - // Most props returned here will be necessary for the app to work properly (see "SSRPageProps") - // Some props are meant to be helpful to the consumer and won't be passed down to the _app.render (e.g: apolloClient, layoutQueryOptions) - return { - props: { - apolloClient, - bestCountryCodes, - serializedDataset: null, // We don't send the dataset yet (we don't have any because we haven't fetched the database yet), but it must be done by SSR pages in"getServerSideProps" - customerRef, - i18nTranslations, - headers: publicHeaders, - gcmsLocales, - hasLocaleFromUrl, - isReadyToRender: true, - isServerRendering: true, - lang, - locale, - layoutQueryOptions, - readonlyCookies, - userSession, - isQuickPreviewPage, - }, }; + + return getServerSideProps; }; diff --git a/src/layouts/core/types/GetCoreLayoutServerSideProps.ts b/src/layouts/core/types/GetCoreLayoutServerSideProps.ts new file mode 100644 index 00000000..21f14ba6 --- /dev/null +++ b/src/layouts/core/types/GetCoreLayoutServerSideProps.ts @@ -0,0 +1,23 @@ +import { CommonServerSideParams } from '@/app/types/CommonServerSideParams'; +import { GetCoreLayoutServerSidePropsResults } from '@/layouts/core/coreLayoutSSR'; +import { GetServerSideProps } from 'next'; + +/** + * The getCoreLayoutServerSideProps is a function returning a getServerSideProps function. + * + * The reason behind this choice are flexibility and code re-usability. + * It makes it possible to customize the behavior of the core "getServerSideProps" function by providing options. + */ +export type GetCoreLayoutServerSideProps = (options?: GetCoreServerSidePropsOptions) => GetServerSideProps; + +/** + * Options allowed in GetCoreLayoutServerSideProps function. + */ +export type GetCoreServerSidePropsOptions = { + /** + * Whether allowing any redirection to a 404 page. + * + * @default true + */ + enable404Redirect: boolean; +}; diff --git a/src/layouts/core/types/GetCoreLayoutStaticPaths.ts b/src/layouts/core/types/GetCoreLayoutStaticPaths.ts new file mode 100644 index 00000000..121ed233 --- /dev/null +++ b/src/layouts/core/types/GetCoreLayoutStaticPaths.ts @@ -0,0 +1,25 @@ +import { CommonServerSideParams } from '@/app/types/CommonServerSideParams'; +import { GetStaticPaths } from 'next'; + +/** + * The getCoreLayoutStaticPaths is a function returning a getStaticPaths function. + * + * The reason behind this choice are flexibility and code re-usability. + * It makes it possible to customize the behavior of the core "getStaticProps" function by providing options. + */ +export type GetCoreLayoutStaticPaths = (options?: GetCoreLayoutStaticPathsOptions) => GetStaticPaths; + +/** + * Options allowed in GetCoreLayoutStaticPaths function. + */ +export type GetCoreLayoutStaticPathsOptions = { + /** + * Enables fallback mode. + * + * @default false + * + * @see https://nextjs.org/docs/basic-features/data-fetching#fallback-true + * @see https://nextjs.org/docs/basic-features/data-fetching#the-fallback-key-required + */ + fallback: boolean; +}; diff --git a/src/layouts/core/types/GetCoreLayoutStaticProps.ts b/src/layouts/core/types/GetCoreLayoutStaticProps.ts new file mode 100644 index 00000000..53f7355b --- /dev/null +++ b/src/layouts/core/types/GetCoreLayoutStaticProps.ts @@ -0,0 +1,26 @@ +import { CommonServerSideParams } from '@/app/types/CommonServerSideParams'; +import { SSGPageProps } from '@/layouts/core/types/SSGPageProps'; +import { GetStaticProps } from 'next'; + +/** + * The getCoreLayoutStaticProps is a function returning a getStaticProps function. + * + * The reason behind this choice are flexibility and code re-usability. + * It makes it possible to customize the behavior of the core "getStaticProps" function by providing options. + * + * This is necessary for the 404 page, which must never return a { notFound: true } object. + * It allows to conditionally return { notFound: true }, and avoid doing so for that particular page. + */ +export type GetCoreLayoutStaticProps = (options?: GetCoreLayoutStaticPropsOptions) => GetStaticProps; + +/** + * Options allowed in GetCoreLayoutStaticProps function. + */ +export type GetCoreLayoutStaticPropsOptions = { + /** + * Whether allowing any redirection to a 404 page. + * + * @default true + */ + enable404Redirect: boolean; +}; diff --git a/src/layouts/demo/demoLayoutSSG.ts b/src/layouts/demo/demoLayoutSSG.ts index 8a1cd28e..3e29aaec 100644 --- a/src/layouts/demo/demoLayoutSSG.ts +++ b/src/layouts/demo/demoLayoutSSG.ts @@ -4,6 +4,14 @@ import { StaticPathsOutput } from '@/app/types/StaticPathsOutput'; import { StaticPropsInput } from '@/app/types/StaticPropsInput'; import { DEMO_LAYOUT_QUERY } from '@/common/gql/demoLayoutQuery'; import { SSGPageProps } from '@/layouts/core/types/SSGPageProps'; +import { + GetDemoLayoutStaticPaths, + GetDemoLayoutStaticPathsOptions, +} from '@/layouts/demo/types/GetDemoLayoutStaticPaths'; +import { + GetDemoLayoutStaticProps, + GetDemoLayoutStaticPropsOptions, +} from '@/layouts/demo/types/GetDemoLayoutStaticProps'; import { APOLLO_STATE_PROP_NAME, getApolloState, @@ -46,137 +54,164 @@ const logger = createLogger({ }); /** - * Only executed on the server side at build time. - * Computes all static paths that should be available for all SSG pages. - * Necessary when a page has dynamic routes and uses "getStaticProps", in order to build the HTML pages. - * - * You can use "fallback" option to avoid building all page variants and allow runtime fallback. - * - * Meant to avoid code duplication between pages sharing the same layout. - * Can be overridden for per-page customisation (e.g: deepmerge). - * - * XXX Demo component, not meant to be modified. It's a copy of the baseSSG implementation, so the demo keep working even if you change the base implementation. + * Returns a "getStaticPaths" function. * - * @return Static paths that will be used by "getCoreStaticProps" to generate pages - * - * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticpaths-static-generation + * @param options */ -export const getDemoStaticPaths: GetStaticPaths = async (context: GetStaticPathsContext): Promise => { - const lang = DEFAULT_LOCALE; - const bestCountryCodes: string[] = [lang, resolveFallbackLanguage(lang)]; - const gcmsLocales: string = prepareGraphCMSLocaleHeader(bestCountryCodes); - const dataset: StaticDataset | GraphCMSDataset = await getGraphcmsDataset(gcmsLocales); - const customer: StaticCustomer | Customer = dataset?.customer; - - // Generate only pages for languages that have been allowed by the customer - const paths: StaticPath[] = map(customer?.availableLanguages, (availableLanguage: string): StaticPath => { +export const getDemoLayoutStaticPaths: GetDemoLayoutStaticPaths = (options?: GetDemoLayoutStaticPathsOptions) => { + const { + fallback = false, + } = options || {}; + + /** + * Only executed on the server side at build time. + * Computes all static paths that should be available for all SSG pages. + * Necessary when a page has dynamic routes and uses "getStaticProps", in order to build the HTML pages. + * + * You can use "fallback" option to avoid building all page variants and allow runtime fallback. + * + * Meant to avoid code duplication between pages sharing the same layout. + * Can be overridden for per-page customisation (e.g: deepmerge). + * + * XXX Demo component, not meant to be modified. It's a copy of the baseSSG implementation, so the demo keep working even if you change the base implementation. + * + * @return Static paths that will be used by "getCoreLayoutStaticProps" to generate pages + * + * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticpaths-static-generation + */ + const getStaticPaths: GetStaticPaths = async (context: GetStaticPathsContext): Promise => { + const lang = DEFAULT_LOCALE; + const bestCountryCodes: string[] = [lang, resolveFallbackLanguage(lang)]; + const gcmsLocales: string = prepareGraphCMSLocaleHeader(bestCountryCodes); + const dataset: StaticDataset | GraphCMSDataset = await getGraphcmsDataset(gcmsLocales); + const customer: StaticCustomer | Customer = dataset?.customer; + + // Generate only pages for languages that have been allowed by the customer + const paths: StaticPath[] = map(customer?.availableLanguages, (availableLanguage: string): StaticPath => { + return { + params: { + locale: availableLanguage, + }, + }; + }); + return { - params: { - locale: availableLanguage, - }, + fallback, + paths, }; - }); - - return { - fallback: false, - paths, }; + + return getStaticPaths; }; /** - * Only executed on the server side at build time. - * Computes all static props that should be available for all SSG pages. + * Returns a "getStaticProps" function. * - * Note that when a page uses "getStaticProps", then "_app:getInitialProps" is executed (if defined) but not actually used by the page, - * only the results from getStaticProps are actually injected into the page (as "SSGPageProps"). + * Disables redirecting to the 404 page when building the 404 page. * - * Meant to avoid code duplication between pages sharing the same layout. - * Can be overridden for per-page customisation (e.g: deepmerge). - * - * XXX Demo component, not meant to be modified. It's a copy of the coreLayoutSSG implementation, so the demo keep working even if you change the base implementation. - - * @return Props (as "SSGPageProps") that will be passed to the Page component, as props (known as "pageProps" in _app). - * - * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 - * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation + * @param options */ -export const getDemoStaticProps: GetStaticProps = async (props: StaticPropsInput): Promise> => { - const customerRef: string = process.env.NEXT_PUBLIC_CUSTOMER_REF; - const preview: boolean = props?.preview || false; - const previewData: PreviewData = props?.previewData || null; - const hasLocaleFromUrl = !!props?.params?.locale; - const locale: string = hasLocaleFromUrl ? props?.params?.locale : DEFAULT_LOCALE; // If the locale isn't found (e.g: 404 page) - const lang: string = locale.split('-')?.[0]; - const bestCountryCodes: string[] = [lang, resolveFallbackLanguage(lang)]; - const gcmsLocales: string = prepareGraphCMSLocaleHeader(bestCountryCodes); - const i18nTranslations: I18nextResources = await getLocizeTranslations(lang); - // XXX This part is not using "getGraphcmsDataset" because I'm not sure how to return the "apolloClient" instance when doing so, as it'll be wrapped and isn't returned - // So, code is duplicated, but that works fine - const apolloClient: ApolloClient = initializeApollo(); - const variables = { - customerRef, - }; - const queryOptions = { - displayName: 'DEMO_LAYOUT_QUERY', - query: DEMO_LAYOUT_QUERY, - variables, - context: { - headers: { - 'gcms-locales': gcmsLocales, +export const getDemoLayoutStaticProps: GetDemoLayoutStaticProps = (options?: GetDemoLayoutStaticPropsOptions) => { + const { + enable404Redirect = true, + } = options || {}; + + /** + * Only executed on the server side at build time. + * Computes all static props that should be available for all SSG pages. + * + * Note that when a page uses "getStaticProps", then "_app:getInitialProps" is executed (if defined) but not actually used by the page, + * only the results from getStaticProps are actually injected into the page (as "SSGPageProps"). + * + * Meant to avoid code duplication between pages sharing the same layout. + * Can be overridden for per-page customisation (e.g: deepmerge). + * + * XXX Demo component, not meant to be modified. It's a copy of the coreLayoutSSG implementation, so the demo keep working even if you change the base implementation. + + * @return Props (as "SSGPageProps") that will be passed to the Page component, as props (known as "pageProps" in _app). + * + * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 + * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation + */ + const getStaticProps: GetStaticProps = async (props: StaticPropsInput): Promise> => { + const customerRef: string = process.env.NEXT_PUBLIC_CUSTOMER_REF; + const preview: boolean = props?.preview || false; + const previewData: PreviewData = props?.previewData || null; + const hasLocaleFromUrl = !!props?.params?.locale; + const locale: string = hasLocaleFromUrl ? props?.params?.locale : DEFAULT_LOCALE; // If the locale isn't found (e.g: 404 page) + const lang: string = locale.split('-')?.[0]; + const bestCountryCodes: string[] = [lang, resolveFallbackLanguage(lang)]; + const gcmsLocales: string = prepareGraphCMSLocaleHeader(bestCountryCodes); + const i18nTranslations: I18nextResources = await getLocizeTranslations(lang); + // XXX This part is not using "getGraphcmsDataset" because I'm not sure how to return the "apolloClient" instance when doing so, as it'll be wrapped and isn't returned + // So, code is duplicated, but that works fine + const apolloClient: ApolloClient = initializeApollo(); + const variables = { + customerRef, + }; + const queryOptions = { + displayName: 'DEMO_LAYOUT_QUERY', + query: DEMO_LAYOUT_QUERY, + variables, + context: { + headers: { + 'gcms-locales': gcmsLocales, + }, }, - }, - }; + }; - const { - data, - errors, - loading, - networkStatus, - ...rest - }: ApolloQueryResult<{ - customer: Customer; - }> = await apolloClient.query(queryOptions); - - if (errors) { - // eslint-disable-next-line no-console - console.error(errors); - throw new Error('Errors were detected in GraphQL query.'); - } + const { + data, + errors, + loading, + networkStatus, + ...rest + }: ApolloQueryResult<{ + customer: Customer; + }> = await apolloClient.query(queryOptions); - const { - customer, - } = data || {}; // XXX Use empty object as fallback, to avoid app crash when destructuring, if no data is returned - const dataset = { - customer, - }; + if (errors) { + // eslint-disable-next-line no-console + console.error(errors); + throw new Error('Errors were detected in GraphQL query.'); + } + + const { + customer, + } = data || {}; // XXX Use empty object as fallback, to avoid app crash when destructuring, if no data is returned + const dataset = { + customer, + }; - // Do not serve pages using locales the customer doesn't have enabled (useful during preview mode and in development env) - if (!includes(customer?.availableLanguages, locale)) { - logger.warn(`Locale "${locale}" not enabled for this customer (allowed: "${customer?.availableLanguages}"), returning 404 page.`); + // Do not serve pages using locales the customer doesn't have enabled (useful during preview mode and in development env) + if (enable404Redirect && !includes(customer?.availableLanguages, locale)) { + logger.warn(`Locale "${locale}" not enabled for this customer (allowed: "${customer?.availableLanguages}"), returning 404 page.`); + + return { + notFound: true, + }; + } return { - notFound: true, + // Props returned here will be available as page properties (pageProps) + props: { + [APOLLO_STATE_PROP_NAME]: getApolloState(apolloClient), + bestCountryCodes, + serializedDataset: serializeSafe(dataset), + customer, + customerRef, + i18nTranslations, + gcmsLocales, + hasLocaleFromUrl, + isReadyToRender: true, + isStaticRendering: true, + lang, + locale, + preview, + previewData, + }, }; - } - - return { - // Props returned here will be available as page properties (pageProps) - props: { - [APOLLO_STATE_PROP_NAME]: getApolloState(apolloClient), - bestCountryCodes, - serializedDataset: serializeSafe(dataset), - customer, - customerRef, - i18nTranslations, - gcmsLocales, - hasLocaleFromUrl, - isReadyToRender: true, - isStaticRendering: true, - lang, - locale, - preview, - previewData, - }, }; -}; + return getStaticProps; +}; diff --git a/src/layouts/demo/demoLayoutSSR.ts b/src/layouts/demo/demoLayoutSSR.ts index 1f5a21e7..455148a6 100644 --- a/src/layouts/demo/demoLayoutSSR.ts +++ b/src/layouts/demo/demoLayoutSSR.ts @@ -2,6 +2,10 @@ import { CommonServerSideParams } from '@/app/types/CommonServerSideParams'; import { DEMO_LAYOUT_QUERY } from '@/common/gql/demoLayoutQuery'; import { PublicHeaders } from '@/layouts/core/types/PublicHeaders'; import { SSRPageProps } from '@/layouts/core/types/SSRPageProps'; +import { + GetDemoLayoutServerSideProps, + GetDemoLayoutServerSidePropsOptions, +} from '@/layouts/demo/types/GetDemoLayoutServerSideProps'; import { initializeApollo } from '@/modules/core/apollo/apolloClient'; import { Cookies } from '@/modules/core/cookiesManager/types/Cookies'; import UniversalCookiesManager from '@/modules/core/cookiesManager/UniversalCookiesManager'; @@ -42,102 +46,117 @@ const logger = createLogger({ }); /** - * "getDemoServerSideProps" returns only part of the props expected in SSRPageProps. + * "getDemoLayoutServerSideProps" returns only part of the props expected in SSRPageProps. * To avoid TS errors, we omit those that we don't return, and add those necessary to the "getServerSideProps" function. */ -export type GetDemoServerSidePropsResults = Omit & { +export type GetDemoLayoutServerSidePropsResults = Omit & { apolloClient: ApolloClient; layoutQueryOptions: ApolloQueryOptions; headers: PublicHeaders; } /** - * Only executed on the server side, for every request. - * Computes some dynamic props that should be available for all SSR pages that use getServerSideProps. - * - * Because the exact GQL query will depend on the consumer (AKA "caller"), this helper doesn't run any query by itself, but rather return all necessary props to allow the consumer to perform its own queries. - * This improves performances, by only running one GQL query instead of many (consumer's choice). + * Returns a "getServerSideProps" function. * - * Meant to avoid code duplication between pages sharing the same layout. + * Disables redirecting to the 404 page when building the 404 page. * - * XXX Demo component, not meant to be modified. It's a copy of the coreLayoutSSR implementation, so the demo keep working even if you change the base implementation. - * - * @see https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering + * @param options */ -export const getDemoServerSideProps: GetServerSideProps = async (context: GetServerSidePropsContext): Promise> => { +export const getDemoLayoutServerSideProps: GetDemoLayoutServerSideProps = (options?: GetDemoLayoutServerSidePropsOptions) => { const { - query, - params, - req, - res, - ...rest - } = context; - const isQuickPreviewPage: boolean = isQuickPreviewRequest(req); - const customerRef: string = process.env.NEXT_PUBLIC_CUSTOMER_REF; - const readonlyCookies: Cookies = NextCookies(context); // Parses Next.js cookies in a universal way (server + client) - const cookiesManager: UniversalCookiesManager = new UniversalCookiesManager(req, res); // Cannot be forwarded as pageProps, because contains circular refs - const userSession: UserSemiPersistentSession = cookiesManager.getUserData(); - const { headers }: IncomingMessage = req; - const publicHeaders: PublicHeaders = { - 'accept-language': headers?.['accept-language'], - 'user-agent': headers?.['user-agent'], - 'host': headers?.host, - }; - const hasLocaleFromUrl = !!query?.locale; - const locale: string = resolveSSRLocale(query, req, readonlyCookies); - const lang: string = locale.split('-')?.[0]; - const bestCountryCodes: string[] = [lang, resolveFallbackLanguage(lang)]; - const gcmsLocales: string = prepareGraphCMSLocaleHeader(bestCountryCodes); - const i18nTranslations: I18nextResources = await getLocizeTranslations(lang); - // XXX This part is not using "getGraphcmsDataset" because I'm not sure how to return the "apolloClient" instance when doing so, as it'll be wrapped and isn't returned - // So, code is duplicated, but that works fine - const apolloClient: ApolloClient = initializeApollo(); - const variables = { - customerRef, - }; - const layoutQueryOptions: ApolloQueryOptions = { - displayName: 'DEMO_LAYOUT_QUERY', - query: DEMO_LAYOUT_QUERY, - variables, - context: { - headers: { - 'gcms-locales': gcmsLocales, + enable404Redirect = true, + } = options || {}; + + /** + * Only executed on the server side, for every request. + * Computes some dynamic props that should be available for all SSR pages that use getServerSideProps. + * + * Because the exact GQL query will depend on the consumer (AKA "caller"), this helper doesn't run any query by itself, but rather return all necessary props to allow the consumer to perform its own queries. + * This improves performances, by only running one GQL query instead of many (consumer's choice). + * + * Meant to avoid code duplication between pages sharing the same layout. + * + * XXX Demo component, not meant to be modified. It's a copy of the coreLayoutSSR implementation, so the demo keep working even if you change the base implementation. + * + * @see https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering + */ + const getServerSideProps: GetServerSideProps = async (context: GetServerSidePropsContext): Promise> => { + const { + query, + params, + req, + res, + ...rest + } = context; + const isQuickPreviewPage: boolean = isQuickPreviewRequest(req); + const customerRef: string = process.env.NEXT_PUBLIC_CUSTOMER_REF; + const readonlyCookies: Cookies = NextCookies(context); // Parses Next.js cookies in a universal way (server + client) + const cookiesManager: UniversalCookiesManager = new UniversalCookiesManager(req, res); // Cannot be forwarded as pageProps, because contains circular refs + const userSession: UserSemiPersistentSession = cookiesManager.getUserData(); + const { headers }: IncomingMessage = req; + const publicHeaders: PublicHeaders = { + 'accept-language': headers?.['accept-language'], + 'user-agent': headers?.['user-agent'], + 'host': headers?.host, + }; + const hasLocaleFromUrl = !!query?.locale; + const locale: string = resolveSSRLocale(query, req, readonlyCookies); + const lang: string = locale.split('-')?.[0]; + const bestCountryCodes: string[] = [lang, resolveFallbackLanguage(lang)]; + const gcmsLocales: string = prepareGraphCMSLocaleHeader(bestCountryCodes); + const i18nTranslations: I18nextResources = await getLocizeTranslations(lang); + // XXX This part is not using "getGraphcmsDataset" because I'm not sure how to return the "apolloClient" instance when doing so, as it'll be wrapped and isn't returned + // So, code is duplicated, but that works fine + const apolloClient: ApolloClient = initializeApollo(); + const variables = { + customerRef, + }; + const layoutQueryOptions: ApolloQueryOptions = { + displayName: 'DEMO_LAYOUT_QUERY', + query: DEMO_LAYOUT_QUERY, + variables, + context: { + headers: { + 'gcms-locales': gcmsLocales, + }, }, - }, - }; + }; + + const dataset: StaticDataset | GraphCMSDataset = await getGraphcmsDataset(gcmsLocales); + const customer: StaticCustomer | Customer = dataset?.customer; - const dataset: StaticDataset | GraphCMSDataset = await getGraphcmsDataset(gcmsLocales); - const customer: StaticCustomer | Customer = dataset?.customer; + // Do not serve pages using locales the customer doesn't have enabled + if (enable404Redirect && !includes(customer?.availableLanguages, locale)) { + logger.warn(`Locale "${locale}" not enabled for this customer (allowed: "${customer?.availableLanguages}"), returning 404 page.`); - // Do not serve pages using locales the customer doesn't have enabled - if (!includes(customer?.availableLanguages, locale)) { - logger.warn(`Locale "${locale}" not enabled for this customer (allowed: "${customer?.availableLanguages}"), returning 404 page.`); + return { + notFound: true, + }; + } + // Most props returned here will be necessary for the app to work properly (see "SSRPageProps") + // Some props are meant to be helpful to the consumer and won't be passed down to the _app.render (e.g: apolloClient, layoutQueryOptions) return { - notFound: true, + props: { + apolloClient, + bestCountryCodes, + serializedDataset: null, // We don't send the dataset yet (we don't have any because we haven't fetched the database yet), but it must be done by SSR pages in"getServerSideProps" + customerRef, + i18nTranslations, + headers: publicHeaders, + gcmsLocales, + hasLocaleFromUrl, + isReadyToRender: true, + isServerRendering: true, + lang, + locale, + layoutQueryOptions, + readonlyCookies, + userSession, + isQuickPreviewPage, + }, }; - } - - // Most props returned here will be necessary for the app to work properly (see "SSRPageProps") - // Some props are meant to be helpful to the consumer and won't be passed down to the _app.render (e.g: apolloClient, layoutQueryOptions) - return { - props: { - apolloClient, - bestCountryCodes, - serializedDataset: null, // We don't send the dataset yet (we don't have any because we haven't fetched the database yet), but it must be done by SSR pages in"getServerSideProps" - customerRef, - i18nTranslations, - headers: publicHeaders, - gcmsLocales, - hasLocaleFromUrl, - isReadyToRender: true, - isServerRendering: true, - lang, - locale, - layoutQueryOptions, - readonlyCookies, - userSession, - isQuickPreviewPage, - }, }; + + return getServerSideProps; }; diff --git a/src/layouts/demo/types/GetDemoLayoutServerSideProps.ts b/src/layouts/demo/types/GetDemoLayoutServerSideProps.ts new file mode 100644 index 00000000..a8c26269 --- /dev/null +++ b/src/layouts/demo/types/GetDemoLayoutServerSideProps.ts @@ -0,0 +1,17 @@ +import { CommonServerSideParams } from '@/app/types/CommonServerSideParams'; +import { GetCoreServerSidePropsOptions } from '@/layouts/core/types/GetCoreLayoutServerSideProps'; +import { GetDemoLayoutServerSidePropsResults } from '@/layouts/demo/demoLayoutSSR'; +import { GetServerSideProps } from 'next'; + +/** + * The getDemoLayoutServerSideProps is a function returning a getServerSideProps function. + * + * The reason behind this choice are flexibility and code re-usability. + * It makes it possible to customize the behavior of the core "getServerSideProps" function by providing options. + */ +export type GetDemoLayoutServerSideProps = (options?: GetDemoLayoutServerSidePropsOptions) => GetServerSideProps; + +/** + * Options allowed in GetDemoLayoutServerSideProps function. + */ +export type GetDemoLayoutServerSidePropsOptions = GetCoreServerSidePropsOptions; diff --git a/src/layouts/demo/types/GetDemoLayoutStaticPaths.ts b/src/layouts/demo/types/GetDemoLayoutStaticPaths.ts new file mode 100644 index 00000000..a1a870d3 --- /dev/null +++ b/src/layouts/demo/types/GetDemoLayoutStaticPaths.ts @@ -0,0 +1,16 @@ +import { CommonServerSideParams } from '@/app/types/CommonServerSideParams'; +import { GetCoreLayoutStaticPathsOptions } from '@/layouts/core/types/GetCoreLayoutStaticPaths'; +import { GetStaticPaths } from 'next'; + +/** + * The getDemoLayoutStaticPaths is a function returning a getStaticPaths function. + * + * The reason behind this choice are flexibility and code re-usability. + * It makes it possible to customize the behavior of the core "getStaticProps" function by providing options. + */ +export type GetDemoLayoutStaticPaths = (options?: GetDemoLayoutStaticPathsOptions) => GetStaticPaths; + +/** + * Options allowed in GetDemoLayoutStaticPaths function. + */ +export type GetDemoLayoutStaticPathsOptions = GetCoreLayoutStaticPathsOptions; diff --git a/src/layouts/demo/types/GetDemoLayoutStaticProps.ts b/src/layouts/demo/types/GetDemoLayoutStaticProps.ts new file mode 100644 index 00000000..44de29e9 --- /dev/null +++ b/src/layouts/demo/types/GetDemoLayoutStaticProps.ts @@ -0,0 +1,20 @@ +import { CommonServerSideParams } from '@/app/types/CommonServerSideParams'; +import { GetCoreLayoutStaticPropsOptions } from '@/layouts/core/types/GetCoreLayoutStaticProps'; +import { SSGPageProps } from '@/layouts/core/types/SSGPageProps'; +import { GetStaticProps } from 'next'; + +/** + * The getDemoLayoutStaticProps is a function returning a getStaticProps function. + * + * The reason behind this choice are flexibility and code re-usability. + * It makes it possible to customize the behavior of the core "getStaticProps" function by providing options. + * + * This is necessary for the 404 page, which must never return a { notFound: true } object. + * It allows to conditionally return { notFound: true }, and avoid doing so for that particular page. + */ +export type GetDemoLayoutStaticProps = (options?: GetDemoLayoutStaticPropsOptions) => GetStaticProps; + +/** + * Options allowed in GetDemoLayoutStaticProps function. + */ +export type GetDemoLayoutStaticPropsOptions = GetCoreLayoutStaticPropsOptions; diff --git a/src/layouts/public/pagePublicTemplateSSG.tsx b/src/layouts/public/pagePublicTemplateSSG.tsx index 6080cec7..e55ac153 100644 --- a/src/layouts/public/pagePublicTemplateSSG.tsx +++ b/src/layouts/public/pagePublicTemplateSSG.tsx @@ -28,7 +28,7 @@ const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript- * Only executed on the server side at build time. * Necessary when a page has dynamic routes and uses "getStaticProps". */ -export const getStaticPaths: GetStaticPaths = getPublicLayoutStaticPaths; +export const getStaticPaths: GetStaticPaths = getPublicLayoutStaticPaths(); /** * Fetches mocked data. @@ -40,7 +40,7 @@ export const getStaticPaths: GetStaticPaths = getPublicL * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ -export const getStaticProps: GetStaticProps = getPublicLayoutStaticProps; +export const getStaticProps: GetStaticProps = getPublicLayoutStaticProps(); /** * SSG pages are first rendered by the server (during static bundling). diff --git a/src/layouts/public/pagePublicTemplateSSR.tsx b/src/layouts/public/pagePublicTemplateSSR.tsx index 54bf1792..92cfbdf9 100644 --- a/src/layouts/public/pagePublicTemplateSSR.tsx +++ b/src/layouts/public/pagePublicTemplateSSR.tsx @@ -28,7 +28,7 @@ const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript- * Only executed on the server side at build time. * Necessary when a page has dynamic routes and uses "getStaticProps". */ -export const getServerSideProps: GetServerSideProps = getPublicLayoutServerSideProps; +export const getServerSideProps: GetServerSideProps = getPublicLayoutServerSideProps(); /** * SSR pages are first rendered by the server diff --git a/src/layouts/public/publicLayoutSSG.ts b/src/layouts/public/publicLayoutSSG.ts index 426a39ba..792a47d4 100644 --- a/src/layouts/public/publicLayoutSSG.ts +++ b/src/layouts/public/publicLayoutSSG.ts @@ -4,6 +4,14 @@ import { StaticPathsOutput } from '@/app/types/StaticPathsOutput'; import { StaticPropsInput } from '@/app/types/StaticPropsInput'; import { SSGPageProps } from '@/layouts/core/types/SSGPageProps'; import { mockedStaticDataset } from '@/layouts/public/mockedStaticDataset'; +import { + GetPublicLayoutStaticPaths, + GetPublicLayoutStaticPathsOptions, +} from '@/layouts/public/types/GetPublicLayoutStaticPaths'; +import { + GetPublicLayoutStaticProps, + GetPublicLayoutStaticPropsOptions, +} from '@/layouts/public/types/GetPublicLayoutStaticProps'; import { APOLLO_STATE_PROP_NAME } from '@/modules/core/apollo/apolloClient'; import { Customer } from '@/modules/core/data/types/Customer'; import { getLocizeTranslations } from '@/modules/core/i18n/getLocizeTranslations'; @@ -11,8 +19,10 @@ import { DEFAULT_LOCALE } from '@/modules/core/i18n/i18n'; import { supportedLocales } from '@/modules/core/i18n/i18nConfig'; import { I18nextResources } from '@/modules/core/i18n/i18nextLocize'; import { I18nLocale } from '@/modules/core/i18n/types/I18nLocale'; +import { createLogger } from '@/modules/core/logging/logger'; import { PreviewData } from '@/modules/core/previewMode/types/PreviewData'; import serializeSafe from '@/modules/core/serializeSafe/serializeSafe'; +import includes from 'lodash.includes'; import map from 'lodash.map'; import { GetStaticPaths, @@ -21,83 +31,124 @@ import { GetStaticPropsResult, } from 'next'; +const fileLabel = 'layouts/public/publicLayoutSSG'; +const logger = createLogger({ + fileLabel, +}); + /** - * Only executed on the server side at build time. - * Computes all static paths that should be available for all SSG pages. - * Necessary when a page has dynamic routes and uses "getStaticProps", in order to build the HTML pages. - * - * You can use "fallback" option to avoid building all page variants and allow runtime fallback. - * - * Meant to avoid code duplication between pages sharing the same layout. - * Can be overridden for per-page customisation (e.g: deepmerge). - * - * @return Static paths that will be used by "getCoreStaticProps" to generate pages + * Returns a "getStaticPaths" function. * - * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticpaths-static-generation + * @param options */ -export const getPublicLayoutStaticPaths: GetStaticPaths = async (context: GetStaticPathsContext): Promise => { - const paths: StaticPath[] = map(supportedLocales, (supportedLocale: I18nLocale): StaticPath => { +export const getPublicLayoutStaticPaths: GetPublicLayoutStaticPaths = (options?: GetPublicLayoutStaticPathsOptions) => { + const { + fallback = false, + } = options || {}; + + /** + * Only executed on the server side at build time. + * Computes all static paths that should be available for all SSG pages. + * Necessary when a page has dynamic routes and uses "getStaticProps", in order to build the HTML pages. + * + * You can use "fallback" option to avoid building all page variants and allow runtime fallback. + * + * Meant to avoid code duplication between pages sharing the same layout. + * Can be overridden for per-page customisation (e.g: deepmerge). + * + * @return Static paths that will be used by "getCoreLayoutStaticProps" to generate pages + * + * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticpaths-static-generation + */ + const getStaticPaths: GetStaticPaths = async (context: GetStaticPathsContext): Promise => { + const paths: StaticPath[] = map(supportedLocales, (supportedLocale: I18nLocale): StaticPath => { + return { + params: { + locale: supportedLocale.name, + }, + }; + }); + return { - params: { - locale: supportedLocale.name, - }, + fallback, + paths, }; - }); - - return { - fallback: false, - paths, }; + + return getStaticPaths; }; /** - * XXX This layout comes "naked" (mocked data) with the strictest minimal stuff to build new pages. - * It doesn't run GraphQL queries, and provides the minimal amount of required data for the page to work. + * Returns a "getStaticProps" function. * - * Only executed on the server side at build time. - * Computes all static props that should be available for all SSG pages. + * Disables redirecting to the 404 page when building the 404 page. * - * Note that when a page uses "getStaticProps", then "_app:getInitialProps" is executed (if defined) but not actually used by the page, - * only the results from getStaticProps are actually injected into the page (as "SSGPageProps"). - * - * Meant to avoid code duplication between pages sharing the same layout. - * Can be overridden for per-page customisation (e.g: deepmerge). - * - * @return Props (as "SSGPageProps") that will be passed to the Page component, as props (known as "pageProps" in _app). - * - * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 - * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation + * @param options */ -export const getPublicLayoutStaticProps: GetStaticProps = async (props: StaticPropsInput): Promise> => { - const customerRef: string = process.env.NEXT_PUBLIC_CUSTOMER_REF; - const preview: boolean = props?.preview || false; - const previewData: PreviewData = props?.previewData || null; - const hasLocaleFromUrl = !!props?.params?.locale; - const locale: string = hasLocaleFromUrl ? props?.params?.locale : DEFAULT_LOCALE; // If the locale isn't found (e.g: 404 page) - const lang: string = locale.split('-')?.[0]; - const i18nTranslations: I18nextResources = await getLocizeTranslations(lang); - const customer: Customer = mockedStaticDataset?.customer; +export const getPublicLayoutStaticProps: GetPublicLayoutStaticProps = (options?: GetPublicLayoutStaticPropsOptions): GetStaticProps => { + const { + enable404Redirect = true, + } = options || {}; + + /** + * XXX This layout comes "naked" (mocked data) with the strictest minimal stuff to build new pages. + * It doesn't run GraphQL queries, and provides the minimal amount of required data for the page to work. + * + * Only executed on the server side at build time. + * Computes all static props that should be available for all SSG pages. + * + * Note that when a page uses "getStaticProps", then "_app:getInitialProps" is executed (if defined) but not actually used by the page, + * only the results from getStaticProps are actually injected into the page (as "SSGPageProps"). + * + * Meant to avoid code duplication between pages sharing the same layout. + * Can be overridden for per-page customisation (e.g: deepmerge). + * + * @return Props (as "SSGPageProps") that will be passed to the Page component, as props (known as "pageProps" in _app). + * + * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 + * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation + */ + const getStaticProps: GetStaticProps = async (props: StaticPropsInput): Promise> => { + const customerRef: string = process.env.NEXT_PUBLIC_CUSTOMER_REF; + const preview: boolean = props?.preview || false; + const previewData: PreviewData = props?.previewData || null; + const hasLocaleFromUrl = !!props?.params?.locale; + const locale: string = hasLocaleFromUrl ? props?.params?.locale : DEFAULT_LOCALE; // If the locale isn't found (e.g: 404 page) + const lang: string = locale.split('-')?.[0]; + const i18nTranslations: I18nextResources = await getLocizeTranslations(lang); + const customer: Customer = mockedStaticDataset?.customer; + + // Do not serve pages using locales the customer doesn't have enabled (useful during preview mode and in development env) + if (enable404Redirect && !includes(customer?.availableLanguages, locale)) { + logger.warn(`Locale "${locale}" not enabled for this customer (allowed: "${customer?.availableLanguages}"), returning 404 page.`); + + return { + notFound: true, + }; + } - return { - // Props returned here will be available as page properties (pageProps) - props: { - [APOLLO_STATE_PROP_NAME]: {}, // Empty Apollo cache - bestCountryCodes: [], // We don't need any because we're not calling a GraphQL endpoint using this layout - serializedDataset: serializeSafe({ + return { + // Props returned here will be available as page properties (pageProps) + props: { + [APOLLO_STATE_PROP_NAME]: {}, // Empty Apollo cache + bestCountryCodes: [], // We don't need any because we're not calling a GraphQL endpoint using this layout + serializedDataset: serializeSafe({ + customer, + }), customer, - }), - customer, - customerRef, - i18nTranslations, - gcmsLocales: null, - hasLocaleFromUrl, - isReadyToRender: true, - isStaticRendering: true, - lang, - locale, - preview, - previewData, - }, + customerRef, + i18nTranslations, + gcmsLocales: null, + hasLocaleFromUrl, + isReadyToRender: true, + isStaticRendering: true, + lang, + locale, + preview, + previewData, + }, + }; }; -}; + return getStaticProps; +}; diff --git a/src/layouts/public/publicLayoutSSR.ts b/src/layouts/public/publicLayoutSSR.ts index 34b29402..87265e36 100644 --- a/src/layouts/public/publicLayoutSSR.ts +++ b/src/layouts/public/publicLayoutSSR.ts @@ -2,6 +2,10 @@ import { CommonServerSideParams } from '@/app/types/CommonServerSideParams'; import { PublicHeaders } from '@/layouts/core/types/PublicHeaders'; import { SSRPageProps } from '@/layouts/core/types/SSRPageProps'; import { mockedStaticDataset } from '@/layouts/public/mockedStaticDataset'; +import { + GetPublicLayoutServerSideProps, + GetPublicLayoutServerSidePropsOptions, +} from '@/layouts/public/types/GetPublicLayoutServerSideProps'; import { APOLLO_STATE_PROP_NAME } from '@/modules/core/apollo/apolloClient'; import { Cookies } from '@/modules/core/cookiesManager/types/Cookies'; import UniversalCookiesManager from '@/modules/core/cookiesManager/UniversalCookiesManager'; @@ -32,7 +36,7 @@ const logger = createLogger({ }); /** - * "getDemoServerSideProps" returns only part of the props expected in SSRPageProps. + * "getDemoLayoutServerSideProps" returns only part of the props expected in SSRPageProps. * To avoid TS errors, we omit those that we don't return, and add those necessary to the "getServerSideProps" function. */ export type GetPublicLayoutServerSidePropsResults = SSRPageProps & { @@ -40,79 +44,92 @@ export type GetPublicLayoutServerSidePropsResults = SSRPageProps & { } /** - * XXX This layout comes "naked" (mocked data) with the strictest minimal stuff to build new pages. - * It doesn't run Airtable API requests, and provides the minimal amount of required data for the page to work. - * - * Only executed on the server side, for every request. - * Computes some dynamic props that should be available for all SSR pages that use getServerSideProps. - * - * Because the exact GQL query will depend on the consumer (AKA "caller"), this helper doesn't run any query by itself, but rather return all necessary props to allow the consumer to perform its own queries. - * This improves performances, by only running one GQL query instead of many (consumer's choice). + * Returns a "getServerSideProps" function. * - * Meant to avoid code duplication between pages sharing the same layout. + * Disables redirecting to the 404 page when building the 404 page. * - * XXX Demo component, not meant to be modified. It's a copy of the coreLayoutSSR implementation, so the demo keep working even if you change the base implementation. - * - * @see https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering + * @param options */ -export const getPublicLayoutServerSideProps: GetServerSideProps = async (context: GetServerSidePropsContext): Promise> => { +export const getPublicLayoutServerSideProps: GetPublicLayoutServerSideProps = (options?: GetPublicLayoutServerSidePropsOptions) => { const { - query, - params, - req, - res, - ...rest - } = context; - const isQuickPreviewPage: boolean = isQuickPreviewRequest(req); - const customerRef: string = process.env.NEXT_PUBLIC_CUSTOMER_REF; - const readonlyCookies: Cookies = NextCookies(context); // Parses Next.js cookies in a universal way (server + client) - const cookiesManager: UniversalCookiesManager = new UniversalCookiesManager(req, res); // Cannot be forwarded as pageProps, because contains circular refs - const userSession: UserSemiPersistentSession = cookiesManager.getUserData(); - const { headers }: IncomingMessage = req; - const publicHeaders: PublicHeaders = { - 'accept-language': headers?.['accept-language'], - 'user-agent': headers?.['user-agent'], - 'host': headers?.host, - }; - const hasLocaleFromUrl = !!query?.locale; - const locale: string = resolveSSRLocale(query, req, readonlyCookies); - const lang: string = locale.split('-')?.[0]; - const bestCountryCodes: string[] = [lang, resolveFallbackLanguage(lang)]; - const gcmsLocales: string = prepareGraphCMSLocaleHeader(bestCountryCodes); - const customer: Customer = mockedStaticDataset?.customer; - const i18nTranslations: I18nextResources = await getLocizeTranslations(lang); - - // Do not serve pages using locales the customer doesn't have enabled - if (!includes(customer?.availableLanguages, locale)) { - logger.warn(`Locale "${locale}" not enabled for this customer (allowed: "${customer?.availableLanguages}"), returning 404 page.`); + enable404Redirect = true, + } = options || {}; - return { - notFound: true, + /** + * XXX This layout comes "naked" (mocked data) with the strictest minimal stuff to build new pages. + * It doesn't run Airtable API requests, and provides the minimal amount of required data for the page to work. + * + * Only executed on the server side, for every request. + * Computes some dynamic props that should be available for all SSR pages that use getServerSideProps. + * + * Because the exact GQL query will depend on the consumer (AKA "caller"), this helper doesn't run any query by itself, but rather return all necessary props to allow the consumer to perform its own queries. + * This improves performances, by only running one GQL query instead of many (consumer's choice). + * + * Meant to avoid code duplication between pages sharing the same layout. + * + * @see https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering + */ + const getServerSideProps: GetServerSideProps = async (context: GetServerSidePropsContext): Promise> => { + const { + query, + params, + req, + res, + ...rest + } = context; + const isQuickPreviewPage: boolean = isQuickPreviewRequest(req); + const customerRef: string = process.env.NEXT_PUBLIC_CUSTOMER_REF; + const readonlyCookies: Cookies = NextCookies(context); // Parses Next.js cookies in a universal way (server + client) + const cookiesManager: UniversalCookiesManager = new UniversalCookiesManager(req, res); // Cannot be forwarded as pageProps, because contains circular refs + const userSession: UserSemiPersistentSession = cookiesManager.getUserData(); + const { headers }: IncomingMessage = req; + const publicHeaders: PublicHeaders = { + 'accept-language': headers?.['accept-language'], + 'user-agent': headers?.['user-agent'], + 'host': headers?.host, }; - } + const hasLocaleFromUrl = !!query?.locale; + const locale: string = resolveSSRLocale(query, req, readonlyCookies); + const lang: string = locale.split('-')?.[0]; + const bestCountryCodes: string[] = [lang, resolveFallbackLanguage(lang)]; + const gcmsLocales: string = prepareGraphCMSLocaleHeader(bestCountryCodes); + const customer: Customer = mockedStaticDataset?.customer; + const i18nTranslations: I18nextResources = await getLocizeTranslations(lang); + + // Do not serve pages using locales the customer doesn't have enabled + if (enable404Redirect && !includes(customer?.availableLanguages, locale)) { + logger.warn(`Locale "${locale}" not enabled for this customer (allowed: "${customer?.availableLanguages}"), returning 404 page.`); + + return { + notFound: true, + }; + } - // Most props returned here will be necessary for the app to work properly (see "SSRPageProps") - // Some props are meant to be helpful to the consumer and won't be passed down to the _app.render (e.g: apolloClient, layoutQueryOptions) - return { - props: { - [APOLLO_STATE_PROP_NAME]: {}, // Empty Apollo cache - bestCountryCodes, - serializedDataset: serializeSafe({ + // Most props returned here will be necessary for the app to work properly (see "SSRPageProps") + // Some props are meant to be helpful to the consumer and won't be passed down to the _app.render (e.g: apolloClient, layoutQueryOptions) + return { + props: { + [APOLLO_STATE_PROP_NAME]: {}, // Empty Apollo cache + bestCountryCodes, + serializedDataset: serializeSafe({ + customer, + }), customer, - }), - customer, - customerRef, - i18nTranslations, - gcmsLocales, - headers: publicHeaders, - hasLocaleFromUrl, - isReadyToRender: true, - isServerRendering: true, - lang, - locale, - readonlyCookies, - userSession, - isQuickPreviewPage, - }, + customerRef, + i18nTranslations, + gcmsLocales, + headers: publicHeaders, + hasLocaleFromUrl, + isReadyToRender: true, + isServerRendering: true, + lang, + locale, + readonlyCookies, + userSession, + isQuickPreviewPage, + }, + }; }; + + return getServerSideProps; }; diff --git a/src/layouts/public/types/GetPublicLayoutServerSideProps.ts b/src/layouts/public/types/GetPublicLayoutServerSideProps.ts new file mode 100644 index 00000000..3a07da1e --- /dev/null +++ b/src/layouts/public/types/GetPublicLayoutServerSideProps.ts @@ -0,0 +1,23 @@ +import { CommonServerSideParams } from '@/app/types/CommonServerSideParams'; +import { GetPublicLayoutServerSidePropsResults } from '@/layouts/public/publicLayoutSSR'; +import { GetServerSideProps } from 'next'; + +/** + * The getPublicLayoutServerSideProps is a function returning a getServerSideProps function. + * + * The reason behind this choice are flexibility and code re-usability. + * It makes it possible to customize the behavior of the core "getServerSideProps" function by providing options. + */ +export type GetPublicLayoutServerSideProps = (options?: GetPublicLayoutServerSidePropsOptions) => GetServerSideProps; + +/** + * Options allowed in GetPublicLayoutServerSideProps function. + */ +export type GetPublicLayoutServerSidePropsOptions = { + /** + * Whether allowing any redirection to a 404 page. + * + * @default true + */ + enable404Redirect: boolean; +}; diff --git a/src/layouts/public/types/GetPublicLayoutStaticPaths.ts b/src/layouts/public/types/GetPublicLayoutStaticPaths.ts new file mode 100644 index 00000000..a0bac724 --- /dev/null +++ b/src/layouts/public/types/GetPublicLayoutStaticPaths.ts @@ -0,0 +1,25 @@ +import { CommonServerSideParams } from '@/app/types/CommonServerSideParams'; +import { GetStaticPaths } from 'next'; + +/** + * The getPublicLayoutStaticPaths is a function returning a getStaticPaths function. + * + * The reason behind this choice are flexibility and code re-usability. + * It makes it possible to customize the behavior of the core "getStaticProps" function by providing options. + */ +export type GetPublicLayoutStaticPaths = (options?: GetPublicLayoutStaticPathsOptions) => GetStaticPaths; + +/** + * Options allowed in GetPublicLayoutStaticPaths function. + */ +export type GetPublicLayoutStaticPathsOptions = { + /** + * Enables fallback mode. + * + * @default false + * + * @see https://nextjs.org/docs/basic-features/data-fetching#fallback-true + * @see https://nextjs.org/docs/basic-features/data-fetching#the-fallback-key-required + */ + fallback: boolean; +}; diff --git a/src/layouts/public/types/GetPublicLayoutStaticProps.ts b/src/layouts/public/types/GetPublicLayoutStaticProps.ts new file mode 100644 index 00000000..6f2b5752 --- /dev/null +++ b/src/layouts/public/types/GetPublicLayoutStaticProps.ts @@ -0,0 +1,26 @@ +import { CommonServerSideParams } from '@/app/types/CommonServerSideParams'; +import { SSGPageProps } from '@/layouts/core/types/SSGPageProps'; +import { GetStaticProps } from 'next'; + +/** + * The getPublicLayoutStaticProps is a function returning a getStaticProps function. + * + * The reason behind this choice are flexibility and code re-usability. + * It makes it possible to customize the behavior of the core "getStaticProps" function by providing options. + * + * This is necessary for the 404 page, which must never return a { notFound: true } object. + * It allows to conditionally return { notFound: true }, and avoid doing so for that particular page. + */ +export type GetPublicLayoutStaticProps = (options?: GetPublicLayoutStaticPropsOptions) => GetStaticProps; + +/** + * Options allowed in GetPublicLayoutStaticProps function. + */ +export type GetPublicLayoutStaticPropsOptions = { + /** + * Whether allowing any redirection to a 404 page. + * + * @default true + */ + enable404Redirect: boolean; +}; diff --git a/src/pages/404.tsx b/src/pages/404.tsx index c576a28e..9c2938e6 100644 --- a/src/pages/404.tsx +++ b/src/pages/404.tsx @@ -38,7 +38,7 @@ const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript- * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ -export const getStaticProps: GetStaticProps = getPublicLayoutStaticProps; +export const getStaticProps: GetStaticProps = getPublicLayoutStaticProps({ enable404Redirect: false }); /** * SSG pages are first rendered by the server (during static bundling) diff --git a/src/pages/[locale]/demo/built-in-features/analytics.tsx b/src/pages/[locale]/demo/built-in-features/analytics.tsx index d3c65cd8..f46b362a 100644 --- a/src/pages/[locale]/demo/built-in-features/analytics.tsx +++ b/src/pages/[locale]/demo/built-in-features/analytics.tsx @@ -8,8 +8,8 @@ import BuiltInFeaturesSidebar from '@/layouts/demo/components/BuiltInFeaturesSid import DemoLayout from '@/layouts/demo/components/DemoLayout'; import DemoPage from '@/layouts/demo/components/DemoPage'; import { - getDemoStaticPaths, - getDemoStaticProps, + getDemoLayoutStaticPaths, + getDemoLayoutStaticProps, } from '@/layouts/demo/demoLayoutSSG'; import { LogEvent } from '@/modules/core/amplitude/types/Amplitude'; import { createLogger } from '@/modules/core/logging/logger'; @@ -38,7 +38,7 @@ const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript- * Only executed on the server side at build time * Necessary when a page has dynamic routes and uses "getStaticProps" */ -export const getStaticPaths: GetStaticPaths = getDemoStaticPaths; +export const getStaticPaths: GetStaticPaths = getDemoLayoutStaticPaths(); /** * Only executed on the server side at build time. @@ -48,7 +48,7 @@ export const getStaticPaths: GetStaticPaths = getDemoSta * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ -export const getStaticProps: GetStaticProps = getDemoStaticProps; +export const getStaticProps: GetStaticProps = getDemoLayoutStaticProps(); /** * SSG pages are first rendered by the server (during static bundling) diff --git a/src/pages/[locale]/demo/built-in-features/animations.tsx b/src/pages/[locale]/demo/built-in-features/animations.tsx index 8cb2f8c8..5e44eb73 100644 --- a/src/pages/[locale]/demo/built-in-features/animations.tsx +++ b/src/pages/[locale]/demo/built-in-features/animations.tsx @@ -8,8 +8,8 @@ import BuiltInFeaturesSidebar from '@/layouts/demo/components/BuiltInFeaturesSid import DemoLayout from '@/layouts/demo/components/DemoLayout'; import DemoPage from '@/layouts/demo/components/DemoPage'; import { - getDemoStaticPaths, - getDemoStaticProps, + getDemoLayoutStaticPaths, + getDemoLayoutStaticProps, } from '@/layouts/demo/demoLayoutSSG'; import { createLogger } from '@/modules/core/logging/logger'; import { @@ -29,7 +29,7 @@ const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript- * Only executed on the server side at build time * Necessary when a page has dynamic routes and uses "getStaticProps" */ -export const getStaticPaths: GetStaticPaths = getDemoStaticPaths; +export const getStaticPaths: GetStaticPaths = getDemoLayoutStaticPaths(); /** * Only executed on the server side at build time. @@ -39,7 +39,7 @@ export const getStaticPaths: GetStaticPaths = getDemoSta * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ -export const getStaticProps: GetStaticProps = getDemoStaticProps; +export const getStaticProps: GetStaticProps = getDemoLayoutStaticProps(); /** * SSG pages are first rendered by the server (during static bundling) diff --git a/src/pages/[locale]/demo/built-in-features/cookies-consent.tsx b/src/pages/[locale]/demo/built-in-features/cookies-consent.tsx index c4f444eb..644c74db 100644 --- a/src/pages/[locale]/demo/built-in-features/cookies-consent.tsx +++ b/src/pages/[locale]/demo/built-in-features/cookies-consent.tsx @@ -6,8 +6,8 @@ import BuiltInFeaturesSidebar from '@/layouts/demo/components/BuiltInFeaturesSid import DemoLayout from '@/layouts/demo/components/DemoLayout'; import DemoPage from '@/layouts/demo/components/DemoPage'; import { - getDemoStaticPaths, - getDemoStaticProps, + getDemoLayoutStaticPaths, + getDemoLayoutStaticProps, } from '@/layouts/demo/demoLayoutSSG'; import { LogEvent } from '@/modules/core/amplitude/types/Amplitude'; import I18nLink from '@/modules/core/i18n/components/I18nLink'; @@ -32,7 +32,7 @@ const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript- * Only executed on the server side at build time * Necessary when a page has dynamic routes and uses "getStaticProps" */ -export const getStaticPaths: GetStaticPaths = getDemoStaticPaths; +export const getStaticPaths: GetStaticPaths = getDemoLayoutStaticPaths(); /** * Only executed on the server side at build time. @@ -42,7 +42,7 @@ export const getStaticPaths: GetStaticPaths = getDemoSta * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ -export const getStaticProps: GetStaticProps = getDemoStaticProps; +export const getStaticProps: GetStaticProps = getDemoLayoutStaticProps(); /** * SSG pages are first rendered by the server (during static bundling) diff --git a/src/pages/[locale]/demo/built-in-features/css-in-js.tsx b/src/pages/[locale]/demo/built-in-features/css-in-js.tsx index 7f67ab0b..38a32772 100644 --- a/src/pages/[locale]/demo/built-in-features/css-in-js.tsx +++ b/src/pages/[locale]/demo/built-in-features/css-in-js.tsx @@ -7,8 +7,8 @@ import BuiltInFeaturesSidebar from '@/layouts/demo/components/BuiltInFeaturesSid import DemoLayout from '@/layouts/demo/components/DemoLayout'; import DemoPage from '@/layouts/demo/components/DemoPage'; import { - getDemoStaticPaths, - getDemoStaticProps, + getDemoLayoutStaticPaths, + getDemoLayoutStaticProps, } from '@/layouts/demo/demoLayoutSSG'; import { createLogger } from '@/modules/core/logging/logger'; import { @@ -29,7 +29,7 @@ const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript- * Only executed on the server side at build time * Necessary when a page has dynamic routes and uses "getStaticProps" */ -export const getStaticPaths: GetStaticPaths = getDemoStaticPaths; +export const getStaticPaths: GetStaticPaths = getDemoLayoutStaticPaths(); /** * Only executed on the server side at build time. @@ -39,7 +39,7 @@ export const getStaticPaths: GetStaticPaths = getDemoSta * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ -export const getStaticProps: GetStaticProps = getDemoStaticProps; +export const getStaticProps: GetStaticProps = getDemoLayoutStaticProps(); /** * SSG pages are first rendered by the server (during static bundling) diff --git a/src/pages/[locale]/demo/built-in-features/docs-site.tsx b/src/pages/[locale]/demo/built-in-features/docs-site.tsx index c0321cb9..a61ddcb2 100644 --- a/src/pages/[locale]/demo/built-in-features/docs-site.tsx +++ b/src/pages/[locale]/demo/built-in-features/docs-site.tsx @@ -6,8 +6,8 @@ import BuiltInFeaturesSidebar from '@/layouts/demo/components/BuiltInFeaturesSid import DemoLayout from '@/layouts/demo/components/DemoLayout'; import DemoPage from '@/layouts/demo/components/DemoPage'; import { - getDemoStaticPaths, - getDemoStaticProps, + getDemoLayoutStaticPaths, + getDemoLayoutStaticProps, } from '@/layouts/demo/demoLayoutSSG'; import { createLogger } from '@/modules/core/logging/logger'; import { @@ -28,7 +28,7 @@ const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript- * Only executed on the server side at build time * Necessary when a page has dynamic routes and uses "getStaticProps" */ -export const getStaticPaths: GetStaticPaths = getDemoStaticPaths; +export const getStaticPaths: GetStaticPaths = getDemoLayoutStaticPaths(); /** * Only executed on the server side at build time. @@ -38,7 +38,7 @@ export const getStaticPaths: GetStaticPaths = getDemoSta * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ -export const getStaticProps: GetStaticProps = getDemoStaticProps; +export const getStaticProps: GetStaticProps = getDemoLayoutStaticProps(); /** * SSG pages are first rendered by the server (during static bundling) diff --git a/src/pages/[locale]/demo/built-in-features/graphql.tsx b/src/pages/[locale]/demo/built-in-features/graphql.tsx index 752a3898..ecd2ea37 100644 --- a/src/pages/[locale]/demo/built-in-features/graphql.tsx +++ b/src/pages/[locale]/demo/built-in-features/graphql.tsx @@ -6,8 +6,8 @@ import BuiltInFeaturesSidebar from '@/layouts/demo/components/BuiltInFeaturesSid import DemoLayout from '@/layouts/demo/components/DemoLayout'; import DemoPage from '@/layouts/demo/components/DemoPage'; import { - getDemoStaticPaths, - getDemoStaticProps, + getDemoLayoutStaticPaths, + getDemoLayoutStaticProps, } from '@/layouts/demo/demoLayoutSSG'; import { createLogger } from '@/modules/core/logging/logger'; import { @@ -28,7 +28,7 @@ const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript- * Only executed on the server side at build time * Necessary when a page has dynamic routes and uses "getStaticProps" */ -export const getStaticPaths: GetStaticPaths = getDemoStaticPaths; +export const getStaticPaths: GetStaticPaths = getDemoLayoutStaticPaths(); /** * Only executed on the server side at build time. @@ -38,7 +38,7 @@ export const getStaticPaths: GetStaticPaths = getDemoSta * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ -export const getStaticProps: GetStaticProps = getDemoStaticProps; +export const getStaticProps: GetStaticProps = getDemoLayoutStaticProps(); /** * SSG pages are first rendered by the server (during static bundling) diff --git a/src/pages/[locale]/demo/built-in-features/hosting.tsx b/src/pages/[locale]/demo/built-in-features/hosting.tsx index 197fa456..dc043864 100644 --- a/src/pages/[locale]/demo/built-in-features/hosting.tsx +++ b/src/pages/[locale]/demo/built-in-features/hosting.tsx @@ -6,8 +6,8 @@ import BuiltInFeaturesSidebar from '@/layouts/demo/components/BuiltInFeaturesSid import DemoLayout from '@/layouts/demo/components/DemoLayout'; import DemoPage from '@/layouts/demo/components/DemoPage'; import { - getDemoStaticPaths, - getDemoStaticProps, + getDemoLayoutStaticPaths, + getDemoLayoutStaticProps, } from '@/layouts/demo/demoLayoutSSG'; import { createLogger } from '@/modules/core/logging/logger'; import { @@ -28,7 +28,7 @@ const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript- * Only executed on the server side at build time * Necessary when a page has dynamic routes and uses "getStaticProps" */ -export const getStaticPaths: GetStaticPaths = getDemoStaticPaths; +export const getStaticPaths: GetStaticPaths = getDemoLayoutStaticPaths(); /** * Only executed on the server side at build time. @@ -38,7 +38,7 @@ export const getStaticPaths: GetStaticPaths = getDemoSta * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ -export const getStaticProps: GetStaticProps = getDemoStaticProps; +export const getStaticProps: GetStaticProps = getDemoLayoutStaticProps(); /** * SSG pages are first rendered by the server (during static bundling) diff --git a/src/pages/[locale]/demo/built-in-features/icons.tsx b/src/pages/[locale]/demo/built-in-features/icons.tsx index 839b8a2d..bb94c471 100644 --- a/src/pages/[locale]/demo/built-in-features/icons.tsx +++ b/src/pages/[locale]/demo/built-in-features/icons.tsx @@ -6,8 +6,8 @@ import BuiltInFeaturesSidebar from '@/layouts/demo/components/BuiltInFeaturesSid import DemoLayout from '@/layouts/demo/components/DemoLayout'; import DemoPage from '@/layouts/demo/components/DemoPage'; import { - getDemoStaticPaths, - getDemoStaticProps, + getDemoLayoutStaticPaths, + getDemoLayoutStaticProps, } from '@/layouts/demo/demoLayoutSSG'; import { createLogger } from '@/modules/core/logging/logger'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; @@ -29,7 +29,7 @@ const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript- * Only executed on the server side at build time * Necessary when a page has dynamic routes and uses "getStaticProps" */ -export const getStaticPaths: GetStaticPaths = getDemoStaticPaths; +export const getStaticPaths: GetStaticPaths = getDemoLayoutStaticPaths(); /** * Only executed on the server side at build time. @@ -39,7 +39,7 @@ export const getStaticPaths: GetStaticPaths = getDemoSta * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ -export const getStaticProps: GetStaticProps = getDemoStaticProps; +export const getStaticProps: GetStaticProps = getDemoLayoutStaticProps(); /** * SSG pages are first rendered by the server (during static bundling) diff --git a/src/pages/[locale]/demo/built-in-features/manual-deployments.tsx b/src/pages/[locale]/demo/built-in-features/manual-deployments.tsx index 8a254299..be0adb9b 100644 --- a/src/pages/[locale]/demo/built-in-features/manual-deployments.tsx +++ b/src/pages/[locale]/demo/built-in-features/manual-deployments.tsx @@ -6,8 +6,8 @@ import BuiltInFeaturesSidebar from '@/layouts/demo/components/BuiltInFeaturesSid import DemoLayout from '@/layouts/demo/components/DemoLayout'; import DemoPage from '@/layouts/demo/components/DemoPage'; import { - getDemoStaticPaths, - getDemoStaticProps, + getDemoLayoutStaticPaths, + getDemoLayoutStaticProps, } from '@/layouts/demo/demoLayoutSSG'; import { createLogger } from '@/modules/core/logging/logger'; import { @@ -28,7 +28,7 @@ const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript- * Only executed on the server side at build time * Necessary when a page has dynamic routes and uses "getStaticProps" */ -export const getStaticPaths: GetStaticPaths = getDemoStaticPaths; +export const getStaticPaths: GetStaticPaths = getDemoLayoutStaticPaths(); /** * Only executed on the server side at build time. @@ -38,7 +38,7 @@ export const getStaticPaths: GetStaticPaths = getDemoSta * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ -export const getStaticProps: GetStaticProps = getDemoStaticProps; +export const getStaticProps: GetStaticProps = getDemoLayoutStaticProps(); /** * SSG pages are first rendered by the server (during static bundling) diff --git a/src/pages/[locale]/demo/built-in-features/monitoring.tsx b/src/pages/[locale]/demo/built-in-features/monitoring.tsx index 03664b7a..81f9e7ed 100644 --- a/src/pages/[locale]/demo/built-in-features/monitoring.tsx +++ b/src/pages/[locale]/demo/built-in-features/monitoring.tsx @@ -6,8 +6,8 @@ import BuiltInFeaturesSidebar from '@/layouts/demo/components/BuiltInFeaturesSid import DemoLayout from '@/layouts/demo/components/DemoLayout'; import DemoPage from '@/layouts/demo/components/DemoPage'; import { - getDemoStaticPaths, - getDemoStaticProps, + getDemoLayoutStaticPaths, + getDemoLayoutStaticProps, } from '@/layouts/demo/demoLayoutSSG'; import { createLogger } from '@/modules/core/logging/logger'; import { @@ -28,7 +28,7 @@ const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript- * Only executed on the server side at build time * Necessary when a page has dynamic routes and uses "getStaticProps" */ -export const getStaticPaths: GetStaticPaths = getDemoStaticPaths; +export const getStaticPaths: GetStaticPaths = getDemoLayoutStaticPaths(); /** * Only executed on the server side at build time. @@ -38,7 +38,7 @@ export const getStaticPaths: GetStaticPaths = getDemoSta * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ -export const getStaticProps: GetStaticProps = getDemoStaticProps; +export const getStaticProps: GetStaticProps = getDemoLayoutStaticProps(); /** * SSG pages are first rendered by the server (during static bundling) diff --git a/src/pages/[locale]/demo/built-in-features/stages-and-secrets.tsx b/src/pages/[locale]/demo/built-in-features/stages-and-secrets.tsx index 184a652a..f20e675c 100644 --- a/src/pages/[locale]/demo/built-in-features/stages-and-secrets.tsx +++ b/src/pages/[locale]/demo/built-in-features/stages-and-secrets.tsx @@ -6,8 +6,8 @@ import BuiltInFeaturesSidebar from '@/layouts/demo/components/BuiltInFeaturesSid import DemoLayout from '@/layouts/demo/components/DemoLayout'; import DemoPage from '@/layouts/demo/components/DemoPage'; import { - getDemoStaticPaths, - getDemoStaticProps, + getDemoLayoutStaticPaths, + getDemoLayoutStaticProps, } from '@/layouts/demo/demoLayoutSSG'; import { createLogger } from '@/modules/core/logging/logger'; import { @@ -28,7 +28,7 @@ const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript- * Only executed on the server side at build time * Necessary when a page has dynamic routes and uses "getStaticProps" */ -export const getStaticPaths: GetStaticPaths = getDemoStaticPaths; +export const getStaticPaths: GetStaticPaths = getDemoLayoutStaticPaths(); /** * Only executed on the server side at build time. @@ -38,7 +38,7 @@ export const getStaticPaths: GetStaticPaths = getDemoSta * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ -export const getStaticProps: GetStaticProps = getDemoStaticProps; +export const getStaticProps: GetStaticProps = getDemoLayoutStaticProps(); /** * SSG pages are first rendered by the server (during static bundling) diff --git a/src/pages/[locale]/demo/built-in-features/static-i18n.tsx b/src/pages/[locale]/demo/built-in-features/static-i18n.tsx index b01c6667..36bae193 100644 --- a/src/pages/[locale]/demo/built-in-features/static-i18n.tsx +++ b/src/pages/[locale]/demo/built-in-features/static-i18n.tsx @@ -8,8 +8,8 @@ import BuiltInFeaturesSidebar from '@/layouts/demo/components/BuiltInFeaturesSid import DemoLayout from '@/layouts/demo/components/DemoLayout'; import DemoPage from '@/layouts/demo/components/DemoPage'; import { - getDemoStaticPaths, - getDemoStaticProps, + getDemoLayoutStaticPaths, + getDemoLayoutStaticProps, } from '@/layouts/demo/demoLayoutSSG'; import useI18n, { I18n } from '@/modules/core/i18n/hooks/useI18n'; import { resolveCustomerVariationLang } from '@/modules/core/i18n/i18n'; @@ -41,7 +41,7 @@ const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript- * Only executed on the server side at build time * Necessary when a page has dynamic routes and uses "getStaticProps" */ -export const getStaticPaths: GetStaticPaths = getDemoStaticPaths; +export const getStaticPaths: GetStaticPaths = getDemoLayoutStaticPaths(); /** * Only executed on the server side at build time. @@ -51,7 +51,7 @@ export const getStaticPaths: GetStaticPaths = getDemoSta * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ -export const getStaticProps: GetStaticProps = getDemoStaticProps; +export const getStaticProps: GetStaticProps = getDemoLayoutStaticProps(); /** * SSG pages are first rendered by the server (during static bundling) diff --git a/src/pages/[locale]/demo/built-in-features/ui-components.tsx b/src/pages/[locale]/demo/built-in-features/ui-components.tsx index 6f9ed1a8..3b123aaa 100644 --- a/src/pages/[locale]/demo/built-in-features/ui-components.tsx +++ b/src/pages/[locale]/demo/built-in-features/ui-components.tsx @@ -8,8 +8,8 @@ import BuiltInFeaturesSidebar from '@/layouts/demo/components/BuiltInFeaturesSid import DemoLayout from '@/layouts/demo/components/DemoLayout'; import DemoPage from '@/layouts/demo/components/DemoPage'; import { - getDemoStaticPaths, - getDemoStaticProps, + getDemoLayoutStaticPaths, + getDemoLayoutStaticProps, } from '@/layouts/demo/demoLayoutSSG'; import { createLogger } from '@/modules/core/logging/logger'; import { @@ -33,7 +33,7 @@ const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript- * Only executed on the server side at build time * Necessary when a page has dynamic routes and uses "getStaticProps" */ -export const getStaticPaths: GetStaticPaths = getDemoStaticPaths; +export const getStaticPaths: GetStaticPaths = getDemoLayoutStaticPaths(); /** * Only executed on the server side at build time. @@ -43,7 +43,7 @@ export const getStaticPaths: GetStaticPaths = getDemoSta * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ -export const getStaticProps: GetStaticProps = getDemoStaticProps; +export const getStaticProps: GetStaticProps = getDemoLayoutStaticProps(); /** * SSG pages are first rendered by the server (during static bundling) diff --git a/src/pages/[locale]/demo/built-in-utilities/api.tsx b/src/pages/[locale]/demo/built-in-utilities/api.tsx index d839389b..2b5d7b0e 100644 --- a/src/pages/[locale]/demo/built-in-utilities/api.tsx +++ b/src/pages/[locale]/demo/built-in-utilities/api.tsx @@ -6,8 +6,8 @@ import BuiltInUtilitiesSidebar from '@/layouts/demo/components/BuiltInUtilitiesS import DemoLayout from '@/layouts/demo/components/DemoLayout'; import DemoPage from '@/layouts/demo/components/DemoPage'; import { - getDemoStaticPaths, - getDemoStaticProps, + getDemoLayoutStaticPaths, + getDemoLayoutStaticProps, } from '@/layouts/demo/demoLayoutSSG'; import { createLogger } from '@/modules/core/logging/logger'; import { css } from '@emotion/react'; @@ -28,7 +28,7 @@ const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript- * Only executed on the server side at build time * Necessary when a page has dynamic routes and uses "getStaticProps" */ -export const getStaticPaths: GetStaticPaths = getDemoStaticPaths; +export const getStaticPaths: GetStaticPaths = getDemoLayoutStaticPaths(); /** * Only executed on the server side at build time. @@ -38,7 +38,7 @@ export const getStaticPaths: GetStaticPaths = getDemoSta * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ -export const getStaticProps: GetStaticProps = getDemoStaticProps; +export const getStaticProps: GetStaticProps = getDemoLayoutStaticProps(); /** * SSG pages are first rendered by the server (during static bundling) diff --git a/src/pages/[locale]/demo/built-in-utilities/bundle-analysis.tsx b/src/pages/[locale]/demo/built-in-utilities/bundle-analysis.tsx index b33c6270..b73ad708 100644 --- a/src/pages/[locale]/demo/built-in-utilities/bundle-analysis.tsx +++ b/src/pages/[locale]/demo/built-in-utilities/bundle-analysis.tsx @@ -6,8 +6,8 @@ import BuiltInUtilitiesSidebar from '@/layouts/demo/components/BuiltInUtilitiesS import DemoLayout from '@/layouts/demo/components/DemoLayout'; import DemoPage from '@/layouts/demo/components/DemoPage'; import { - getDemoStaticPaths, - getDemoStaticProps, + getDemoLayoutStaticPaths, + getDemoLayoutStaticProps, } from '@/layouts/demo/demoLayoutSSG'; import { createLogger } from '@/modules/core/logging/logger'; import { @@ -27,7 +27,7 @@ const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript- * Only executed on the server side at build time * Necessary when a page has dynamic routes and uses "getStaticProps" */ -export const getStaticPaths: GetStaticPaths = getDemoStaticPaths; +export const getStaticPaths: GetStaticPaths = getDemoLayoutStaticPaths(); /** * Only executed on the server side at build time. @@ -37,7 +37,7 @@ export const getStaticPaths: GetStaticPaths = getDemoSta * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ -export const getStaticProps: GetStaticProps = getDemoStaticProps; +export const getStaticProps: GetStaticProps = getDemoLayoutStaticProps(); /** * SSG pages are first rendered by the server (during static bundling) diff --git a/src/pages/[locale]/demo/built-in-utilities/errors-handling.tsx b/src/pages/[locale]/demo/built-in-utilities/errors-handling.tsx index 82c7cc9b..cbd46073 100644 --- a/src/pages/[locale]/demo/built-in-utilities/errors-handling.tsx +++ b/src/pages/[locale]/demo/built-in-utilities/errors-handling.tsx @@ -7,8 +7,8 @@ import BuiltInUtilitiesSidebar from '@/layouts/demo/components/BuiltInUtilitiesS import DemoLayout from '@/layouts/demo/components/DemoLayout'; import DemoPage from '@/layouts/demo/components/DemoPage'; import { - getDemoStaticPaths, - getDemoStaticProps, + getDemoLayoutStaticPaths, + getDemoLayoutStaticProps, } from '@/layouts/demo/demoLayoutSSG'; import I18nLink from '@/modules/core/i18n/components/I18nLink'; import { createLogger } from '@/modules/core/logging/logger'; @@ -30,7 +30,7 @@ const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript- * Only executed on the server side at build time * Necessary when a page has dynamic routes and uses "getStaticProps" */ -export const getStaticPaths: GetStaticPaths = getDemoStaticPaths; +export const getStaticPaths: GetStaticPaths = getDemoLayoutStaticPaths(); /** * Only executed on the server side at build time. @@ -40,7 +40,7 @@ export const getStaticPaths: GetStaticPaths = getDemoSta * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ -export const getStaticProps: GetStaticProps = getDemoStaticProps; +export const getStaticProps: GetStaticProps = getDemoLayoutStaticProps(); /** * SSG pages are first rendered by the server (during static bundling) diff --git a/src/pages/[locale]/demo/built-in-utilities/hooks.tsx b/src/pages/[locale]/demo/built-in-utilities/hooks.tsx index 91bbce0c..7fe1a65d 100644 --- a/src/pages/[locale]/demo/built-in-utilities/hooks.tsx +++ b/src/pages/[locale]/demo/built-in-utilities/hooks.tsx @@ -7,8 +7,8 @@ import BuiltInUtilitiesSidebar from '@/layouts/demo/components/BuiltInUtilitiesS import DemoLayout from '@/layouts/demo/components/DemoLayout'; import DemoPage from '@/layouts/demo/components/DemoPage'; import { - getDemoStaticPaths, - getDemoStaticProps, + getDemoLayoutStaticPaths, + getDemoLayoutStaticProps, } from '@/layouts/demo/demoLayoutSSG'; import { createLogger } from '@/modules/core/logging/logger'; import { css } from '@emotion/react'; @@ -30,7 +30,7 @@ const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript- * Only executed on the server side at build time * Necessary when a page has dynamic routes and uses "getStaticProps" */ -export const getStaticPaths: GetStaticPaths = getDemoStaticPaths; +export const getStaticPaths: GetStaticPaths = getDemoLayoutStaticPaths(); /** * Only executed on the server side at build time. @@ -40,7 +40,7 @@ export const getStaticPaths: GetStaticPaths = getDemoSta * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ -export const getStaticProps: GetStaticProps = getDemoStaticProps; +export const getStaticProps: GetStaticProps = getDemoLayoutStaticProps(); /** * SSG pages are first rendered by the server (during static bundling) diff --git a/src/pages/[locale]/demo/built-in-utilities/i18nLink-component.tsx b/src/pages/[locale]/demo/built-in-utilities/i18nLink-component.tsx index f0525e5a..6ba812cc 100644 --- a/src/pages/[locale]/demo/built-in-utilities/i18nLink-component.tsx +++ b/src/pages/[locale]/demo/built-in-utilities/i18nLink-component.tsx @@ -6,8 +6,8 @@ import BuiltInUtilitiesSidebar from '@/layouts/demo/components/BuiltInUtilitiesS import DemoLayout from '@/layouts/demo/components/DemoLayout'; import DemoPage from '@/layouts/demo/components/DemoPage'; import { - getDemoStaticPaths, - getDemoStaticProps, + getDemoLayoutStaticPaths, + getDemoLayoutStaticProps, } from '@/layouts/demo/demoLayoutSSG'; import I18nLink from '@/modules/core/i18n/components/I18nLink'; import { createLogger } from '@/modules/core/logging/logger'; @@ -29,7 +29,7 @@ const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript- * Only executed on the server side at build time * Necessary when a page has dynamic routes and uses "getStaticProps" */ -export const getStaticPaths: GetStaticPaths = getDemoStaticPaths; +export const getStaticPaths: GetStaticPaths = getDemoLayoutStaticPaths(); /** * Only executed on the server side at build time. @@ -39,7 +39,7 @@ export const getStaticPaths: GetStaticPaths = getDemoSta * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ -export const getStaticProps: GetStaticProps = getDemoStaticProps; +export const getStaticProps: GetStaticProps = getDemoLayoutStaticProps(); /** * SSG pages are first rendered by the server (during static bundling) diff --git a/src/pages/[locale]/demo/built-in-utilities/interactive-error.tsx b/src/pages/[locale]/demo/built-in-utilities/interactive-error.tsx index 4ebb43b1..10f9a9aa 100644 --- a/src/pages/[locale]/demo/built-in-utilities/interactive-error.tsx +++ b/src/pages/[locale]/demo/built-in-utilities/interactive-error.tsx @@ -5,8 +5,8 @@ import { SSGPageProps } from '@/layouts/core/types/SSGPageProps'; import BuiltInUtilitiesSidebar from '@/layouts/demo/components/BuiltInUtilitiesSidebar'; import DemoLayout from '@/layouts/demo/components/DemoLayout'; import { - getDemoStaticPaths, - getDemoStaticProps, + getDemoLayoutStaticPaths, + getDemoLayoutStaticProps, } from '@/layouts/demo/demoLayoutSSG'; import { createLogger } from '@/modules/core/logging/logger'; import { @@ -30,7 +30,7 @@ const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript- * Only executed on the server side at build time * Necessary when a page has dynamic routes and uses "getStaticProps" */ -export const getStaticPaths: GetStaticPaths = getDemoStaticPaths; +export const getStaticPaths: GetStaticPaths = getDemoLayoutStaticPaths(); /** * Only executed on the server side at build time. @@ -40,7 +40,7 @@ export const getStaticPaths: GetStaticPaths = getDemoSta * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ -export const getStaticProps: GetStaticProps = getDemoStaticProps; +export const getStaticProps: GetStaticProps = getDemoLayoutStaticProps(); /** * SSG pages are first rendered by the server (during static bundling) diff --git a/src/pages/[locale]/demo/built-in-utilities/packages-upgrade.tsx b/src/pages/[locale]/demo/built-in-utilities/packages-upgrade.tsx index 01fa3522..57f8c236 100644 --- a/src/pages/[locale]/demo/built-in-utilities/packages-upgrade.tsx +++ b/src/pages/[locale]/demo/built-in-utilities/packages-upgrade.tsx @@ -7,8 +7,8 @@ import BuiltInUtilitiesSidebar from '@/layouts/demo/components/BuiltInUtilitiesS import DemoLayout from '@/layouts/demo/components/DemoLayout'; import DemoPage from '@/layouts/demo/components/DemoPage'; import { - getDemoStaticPaths, - getDemoStaticProps, + getDemoLayoutStaticPaths, + getDemoLayoutStaticProps, } from '@/layouts/demo/demoLayoutSSG'; import { createLogger } from '@/modules/core/logging/logger'; import { @@ -29,7 +29,7 @@ const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript- * Only executed on the server side at build time * Necessary when a page has dynamic routes and uses "getStaticProps" */ -export const getStaticPaths: GetStaticPaths = getDemoStaticPaths; +export const getStaticPaths: GetStaticPaths = getDemoLayoutStaticPaths(); /** * Only executed on the server side at build time. @@ -39,7 +39,7 @@ export const getStaticPaths: GetStaticPaths = getDemoSta * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ -export const getStaticProps: GetStaticProps = getDemoStaticProps; +export const getStaticProps: GetStaticProps = getDemoLayoutStaticProps(); /** * SSG pages are first rendered by the server (during static bundling) diff --git a/src/pages/[locale]/demo/built-in-utilities/security-audit.tsx b/src/pages/[locale]/demo/built-in-utilities/security-audit.tsx index e2d46bcf..aeaeaa9c 100644 --- a/src/pages/[locale]/demo/built-in-utilities/security-audit.tsx +++ b/src/pages/[locale]/demo/built-in-utilities/security-audit.tsx @@ -6,8 +6,8 @@ import BuiltInUtilitiesSidebar from '@/layouts/demo/components/BuiltInUtilitiesS import DemoLayout from '@/layouts/demo/components/DemoLayout'; import DemoPage from '@/layouts/demo/components/DemoPage'; import { - getDemoStaticPaths, - getDemoStaticProps, + getDemoLayoutStaticPaths, + getDemoLayoutStaticProps, } from '@/layouts/demo/demoLayoutSSG'; import { createLogger } from '@/modules/core/logging/logger'; import { @@ -28,7 +28,7 @@ const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript- * Only executed on the server side at build time * Necessary when a page has dynamic routes and uses "getStaticProps" */ -export const getStaticPaths: GetStaticPaths = getDemoStaticPaths; +export const getStaticPaths: GetStaticPaths = getDemoLayoutStaticPaths(); /** * Only executed on the server side at build time. @@ -38,7 +38,7 @@ export const getStaticPaths: GetStaticPaths = getDemoSta * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ -export const getStaticProps: GetStaticProps = getDemoStaticProps; +export const getStaticProps: GetStaticProps = getDemoLayoutStaticProps(); /** * SSG pages are first rendered by the server (during static bundling) diff --git a/src/pages/[locale]/demo/built-in-utilities/svg-to-react.tsx b/src/pages/[locale]/demo/built-in-utilities/svg-to-react.tsx index 98268de5..0a2a7b2d 100644 --- a/src/pages/[locale]/demo/built-in-utilities/svg-to-react.tsx +++ b/src/pages/[locale]/demo/built-in-utilities/svg-to-react.tsx @@ -10,8 +10,8 @@ import BuiltInUtilitiesSidebar from '@/layouts/demo/components/BuiltInUtilitiesS import DemoLayout from '@/layouts/demo/components/DemoLayout'; import DemoPage from '@/layouts/demo/components/DemoPage'; import { - getDemoStaticPaths, - getDemoStaticProps, + getDemoLayoutStaticPaths, + getDemoLayoutStaticProps, } from '@/layouts/demo/demoLayoutSSG'; import { createLogger } from '@/modules/core/logging/logger'; import { css } from '@emotion/react'; @@ -33,7 +33,7 @@ const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript- * Only executed on the server side at build time * Necessary when a page has dynamic routes and uses "getStaticProps" */ -export const getStaticPaths: GetStaticPaths = getDemoStaticPaths; +export const getStaticPaths: GetStaticPaths = getDemoLayoutStaticPaths(); /** * Only executed on the server side at build time. @@ -43,7 +43,7 @@ export const getStaticPaths: GetStaticPaths = getDemoSta * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ -export const getStaticProps: GetStaticProps = getDemoStaticProps; +export const getStaticProps: GetStaticProps = getDemoLayoutStaticProps(); /** * SSG pages are first rendered by the server (during static bundling) diff --git a/src/pages/[locale]/demo/built-in-utilities/top-level-500-error.tsx b/src/pages/[locale]/demo/built-in-utilities/top-level-500-error.tsx index 968f4bab..0b9225d1 100644 --- a/src/pages/[locale]/demo/built-in-utilities/top-level-500-error.tsx +++ b/src/pages/[locale]/demo/built-in-utilities/top-level-500-error.tsx @@ -4,8 +4,8 @@ import { SSGPageProps } from '@/layouts/core/types/SSGPageProps'; import BuiltInUtilitiesSidebar from '@/layouts/demo/components/BuiltInUtilitiesSidebar'; import DemoLayout from '@/layouts/demo/components/DemoLayout'; import { - getDemoStaticPaths, - getDemoStaticProps, + getDemoLayoutStaticPaths, + getDemoLayoutStaticProps, } from '@/layouts/demo/demoLayoutSSG'; import { createLogger } from '@/modules/core/logging/logger'; import { isBrowser } from '@unly/utils'; @@ -26,7 +26,7 @@ const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript- * Only executed on the server side at build time * Necessary when a page has dynamic routes and uses "getStaticProps" */ -export const getStaticPaths: GetStaticPaths = getDemoStaticPaths; +export const getStaticPaths: GetStaticPaths = getDemoLayoutStaticPaths(); /** * Only executed on the server side at build time. @@ -36,7 +36,7 @@ export const getStaticPaths: GetStaticPaths = getDemoSta * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ -export const getStaticProps: GetStaticProps = getDemoStaticProps; +export const getStaticProps: GetStaticProps = getDemoLayoutStaticProps(); /** * SSG pages are first rendered by the server (during static bundling) diff --git a/src/pages/[locale]/demo/built-in-utilities/tracking-useless-re-renders.tsx b/src/pages/[locale]/demo/built-in-utilities/tracking-useless-re-renders.tsx index dd4002f6..3eb829af 100644 --- a/src/pages/[locale]/demo/built-in-utilities/tracking-useless-re-renders.tsx +++ b/src/pages/[locale]/demo/built-in-utilities/tracking-useless-re-renders.tsx @@ -7,8 +7,8 @@ import BuiltInUtilitiesSidebar from '@/layouts/demo/components/BuiltInUtilitiesS import DemoLayout from '@/layouts/demo/components/DemoLayout'; import DemoPage from '@/layouts/demo/components/DemoPage'; import { - getDemoStaticPaths, - getDemoStaticProps, + getDemoLayoutStaticPaths, + getDemoLayoutStaticProps, } from '@/layouts/demo/demoLayoutSSG'; import I18nLink from '@/modules/core/i18n/components/I18nLink'; import { createLogger } from '@/modules/core/logging/logger'; @@ -33,7 +33,7 @@ const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript- * Only executed on the server side at build time * Necessary when a page has dynamic routes and uses "getStaticProps" */ -export const getStaticPaths: GetStaticPaths = getDemoStaticPaths; +export const getStaticPaths: GetStaticPaths = getDemoLayoutStaticPaths(); /** * Only executed on the server side at build time. @@ -43,7 +43,7 @@ export const getStaticPaths: GetStaticPaths = getDemoSta * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ -export const getStaticProps: GetStaticProps = getDemoStaticProps; +export const getStaticProps: GetStaticProps = getDemoLayoutStaticProps(); /** * SSG pages are first rendered by the server (during static bundling) diff --git a/src/pages/[locale]/demo/index.tsx b/src/pages/[locale]/demo/index.tsx index 10375305..4859c190 100644 --- a/src/pages/[locale]/demo/index.tsx +++ b/src/pages/[locale]/demo/index.tsx @@ -8,8 +8,8 @@ import ExternalFeaturesSection from '@/layouts/demo/components/ExternalFeaturesS import IntroductionSection from '@/layouts/demo/components/IntroductionSection'; import NativeFeaturesSection from '@/layouts/demo/components/NativeFeaturesSection'; import { - getDemoStaticPaths, - getDemoStaticProps, + getDemoLayoutStaticPaths, + getDemoLayoutStaticProps, } from '@/layouts/demo/demoLayoutSSG'; import { AMPLITUDE_PAGES } from '@/modules/core/amplitude/amplitude'; import { LogEvent } from '@/modules/core/amplitude/types/Amplitude'; @@ -32,7 +32,7 @@ const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript- * Only executed on the server side at build time * Necessary when a page has dynamic routes and uses "getStaticProps" */ -export const getStaticPaths: GetStaticPaths = getDemoStaticPaths; +export const getStaticPaths: GetStaticPaths = getDemoLayoutStaticPaths(); /** * Only executed on the server side at build time. @@ -42,7 +42,7 @@ export const getStaticPaths: GetStaticPaths = getDemoSta * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ -export const getStaticProps: GetStaticProps = getDemoStaticProps; +export const getStaticProps: GetStaticProps = getDemoLayoutStaticProps(); /** * SSG pages are first rendered by the server (during static bundling) diff --git a/src/pages/[locale]/demo/native-features/example-optional-catch-all-routes/[[...slug]].tsx b/src/pages/[locale]/demo/native-features/example-optional-catch-all-routes/[[...slug]].tsx index 2050a6be..c7155fa2 100644 --- a/src/pages/[locale]/demo/native-features/example-optional-catch-all-routes/[[...slug]].tsx +++ b/src/pages/[locale]/demo/native-features/example-optional-catch-all-routes/[[...slug]].tsx @@ -6,7 +6,7 @@ import { SSGPageProps } from '@/layouts/core/types/SSGPageProps'; import DemoLayout from '@/layouts/demo/components/DemoLayout'; import DemoPage from '@/layouts/demo/components/DemoPage'; import NativeFeaturesSidebar from '@/layouts/demo/components/NativeFeaturesSidebar'; -import { getDemoStaticProps } from '@/layouts/demo/demoLayoutSSG'; +import { getDemoLayoutStaticProps } from '@/layouts/demo/demoLayoutSSG'; import I18nLink from '@/modules/core/i18n/components/I18nLink'; import { supportedLocales } from '@/modules/core/i18n/i18nConfig'; import { I18nLocale } from '@/modules/core/i18n/types/I18nLocale'; @@ -59,7 +59,7 @@ export const getStaticPaths: GetStaticPaths = async (): * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ -export const getStaticProps: GetStaticProps = getDemoStaticProps; +export const getStaticProps: GetStaticProps = getDemoLayoutStaticProps(); /** * SSG pages are first rendered by the server (during static bundling) diff --git a/src/pages/[locale]/demo/native-features/example-with-ssg-and-fallback/[albumId].tsx b/src/pages/[locale]/demo/native-features/example-with-ssg-and-fallback/[albumId].tsx index 80a6e307..adec8073 100644 --- a/src/pages/[locale]/demo/native-features/example-with-ssg-and-fallback/[albumId].tsx +++ b/src/pages/[locale]/demo/native-features/example-with-ssg-and-fallback/[albumId].tsx @@ -10,8 +10,8 @@ import { SSGPageProps } from '@/layouts/core/types/SSGPageProps'; import DemoLayout from '@/layouts/demo/components/DemoLayout'; import NativeFeaturesSidebar from '@/layouts/demo/components/NativeFeaturesSidebar'; import { - getDemoStaticPaths, - getDemoStaticProps, + getDemoLayoutStaticPaths, + getDemoLayoutStaticProps, } from '@/layouts/demo/demoLayoutSSG'; import I18nLink from '@/modules/core/i18n/components/I18nLink'; import { getRandomInt } from '@/modules/core/js/random'; @@ -45,7 +45,7 @@ type PageAdditionalServerSideParams = { * Necessary when a page has dynamic routes and uses "getStaticProps". */ export const getStaticPaths: GetStaticPaths = async (context: GetStaticPathsContext): Promise> => { - const commonStaticPaths: StaticPathsOutput = await getDemoStaticPaths(context) as StaticPathsOutput; + const commonStaticPaths: StaticPathsOutput = await getDemoLayoutStaticPaths()(context) as StaticPathsOutput; const { paths } = commonStaticPaths; const albumIdsToPreBuild = ['1', '2']; // Only '/album-1-with-ssg-and-fallback' and '/album-2-with-ssg-and-fallback' are generated at build time, other will be generated on-demand const preBuiltPaths: StaticPathsOutput = { @@ -77,7 +77,7 @@ export const getStaticPaths: GetStaticPaths = async (con * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ export const getStaticProps: GetStaticProps = async (props: StaticPropsInput): Promise> => { - const commonStaticProps: GetStaticPropsResult = await getDemoStaticProps(props); + const commonStaticProps: GetStaticPropsResult = await getDemoLayoutStaticProps()(props); const { params: { albumId } } = props; // Simulate API call by awaiting diff --git a/src/pages/[locale]/demo/native-features/example-with-ssg-and-revalidate.tsx b/src/pages/[locale]/demo/native-features/example-with-ssg-and-revalidate.tsx index 1d84b2a6..c51da584 100644 --- a/src/pages/[locale]/demo/native-features/example-with-ssg-and-revalidate.tsx +++ b/src/pages/[locale]/demo/native-features/example-with-ssg-and-revalidate.tsx @@ -9,8 +9,8 @@ import { SSGPageProps } from '@/layouts/core/types/SSGPageProps'; import DemoLayout from '@/layouts/demo/components/DemoLayout'; import NativeFeaturesSidebar from '@/layouts/demo/components/NativeFeaturesSidebar'; import { - getDemoStaticPaths, - getDemoStaticProps, + getDemoLayoutStaticPaths, + getDemoLayoutStaticProps, } from '@/layouts/demo/demoLayoutSSG'; import { initializeApollo } from '@/modules/core/apollo/apolloClient'; import { Product } from '@/modules/core/data/types/Product'; @@ -49,7 +49,7 @@ const regenerationDelay = 30; // Seconds * Only executed on the server side at build time * Necessary when a page has dynamic routes and uses "getStaticProps" */ -export const getStaticPaths: GetStaticPaths = getDemoStaticPaths; +export const getStaticPaths: GetStaticPaths = getDemoLayoutStaticPaths(); /** * Only executed on the server side at build time. @@ -60,7 +60,7 @@ export const getStaticPaths: GetStaticPaths = getDemoSta * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ export const getStaticProps: GetStaticProps = async (props: StaticPropsInput): Promise> => { - const commonStaticProps: GetStaticPropsResult = await getDemoStaticProps(props); + const commonStaticProps: GetStaticPropsResult = await getDemoLayoutStaticProps()(props); if ('props' in commonStaticProps) { const { diff --git a/src/pages/[locale]/demo/native-features/example-with-ssg.tsx b/src/pages/[locale]/demo/native-features/example-with-ssg.tsx index 524309d1..016f8ef5 100644 --- a/src/pages/[locale]/demo/native-features/example-with-ssg.tsx +++ b/src/pages/[locale]/demo/native-features/example-with-ssg.tsx @@ -8,8 +8,8 @@ import { SSGPageProps } from '@/layouts/core/types/SSGPageProps'; import DemoLayout from '@/layouts/demo/components/DemoLayout'; import NativeFeaturesSidebar from '@/layouts/demo/components/NativeFeaturesSidebar'; import { - getDemoStaticPaths, - getDemoStaticProps, + getDemoLayoutStaticPaths, + getDemoLayoutStaticProps, } from '@/layouts/demo/demoLayoutSSG'; import { initializeApollo } from '@/modules/core/apollo/apolloClient'; import { Product } from '@/modules/core/data/types/Product'; @@ -48,7 +48,7 @@ const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript- * Only executed on the server side at build time * Necessary when a page has dynamic routes and uses "getStaticProps" */ -export const getStaticPaths: GetStaticPaths = getDemoStaticPaths; +export const getStaticPaths: GetStaticPaths = getDemoLayoutStaticPaths(); /** * Only executed on the server side at build time. @@ -59,7 +59,7 @@ export const getStaticPaths: GetStaticPaths = getDemoSta * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ export const getStaticProps: GetStaticProps = async (props: StaticPropsInput): Promise> => { - const commonStaticProps: GetStaticPropsResult = await getDemoStaticProps(props); + const commonStaticProps: GetStaticPropsResult = await getDemoLayoutStaticProps()(props); if ('props' in commonStaticProps) { const { diff --git a/src/pages/[locale]/demo/native-features/example-with-ssr.tsx b/src/pages/[locale]/demo/native-features/example-with-ssr.tsx index 7adc119e..e4ebae59 100644 --- a/src/pages/[locale]/demo/native-features/example-with-ssr.tsx +++ b/src/pages/[locale]/demo/native-features/example-with-ssr.tsx @@ -8,8 +8,8 @@ import { SSRPageProps } from '@/layouts/core/types/SSRPageProps'; import DemoLayout from '@/layouts/demo/components/DemoLayout'; import NativeFeaturesSidebar from '@/layouts/demo/components/NativeFeaturesSidebar'; import { - GetDemoServerSidePropsResults, - getDemoServerSideProps, + GetDemoLayoutServerSidePropsResults, + getDemoLayoutServerSideProps, } from '@/layouts/demo/demoLayoutSSR'; import { APOLLO_STATE_PROP_NAME, @@ -59,7 +59,7 @@ type GetServerSidePageProps = CustomPageProps & SSRPageProps * @param context */ export const getServerSideProps: GetServerSideProps = async (context: GetServerSidePropsContext): Promise> => { - const commonServerSideProps: GetServerSidePropsResult> = await getDemoServerSideProps(context); + const commonServerSideProps: GetServerSidePropsResult> = await getDemoLayoutServerSideProps()(context); if ('props' in commonServerSideProps) { diff --git a/src/pages/[locale]/demo/privacy.tsx b/src/pages/[locale]/demo/privacy.tsx index 93d24963..479b980c 100644 --- a/src/pages/[locale]/demo/privacy.tsx +++ b/src/pages/[locale]/demo/privacy.tsx @@ -4,8 +4,8 @@ import { OnlyBrowserPageProps } from '@/layouts/core/types/OnlyBrowserPageProps' import { SSGPageProps } from '@/layouts/core/types/SSGPageProps'; import DemoLayout from '@/layouts/demo/components/DemoLayout'; import { - getDemoStaticPaths, - getDemoStaticProps, + getDemoLayoutStaticPaths, + getDemoLayoutStaticProps, } from '@/layouts/demo/demoLayoutSSG'; import { AMPLITUDE_PAGES } from '@/modules/core/amplitude/amplitude'; import useCustomer from '@/modules/core/data/hooks/useCustomer'; @@ -29,7 +29,7 @@ const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript- * Only executed on the server side at build time * Necessary when a page has dynamic routes and uses "getStaticProps" */ -export const getStaticPaths: GetStaticPaths = getDemoStaticPaths; +export const getStaticPaths: GetStaticPaths = getDemoLayoutStaticPaths(); /** * Only executed on the server side at build time. @@ -39,7 +39,7 @@ export const getStaticPaths: GetStaticPaths = getDemoSta * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ -export const getStaticProps: GetStaticProps = getDemoStaticProps; +export const getStaticProps: GetStaticProps = getDemoLayoutStaticProps(); /** * SSG pages are first rendered by the server (during static bundling) diff --git a/src/pages/[locale]/demo/terms.tsx b/src/pages/[locale]/demo/terms.tsx index f074b8f7..d9e93aec 100644 --- a/src/pages/[locale]/demo/terms.tsx +++ b/src/pages/[locale]/demo/terms.tsx @@ -6,8 +6,8 @@ import { OnlyBrowserPageProps } from '@/layouts/core/types/OnlyBrowserPageProps' import { SSGPageProps } from '@/layouts/core/types/SSGPageProps'; import DemoLayout from '@/layouts/demo/components/DemoLayout'; import { - getDemoStaticPaths, - getDemoStaticProps, + getDemoLayoutStaticPaths, + getDemoLayoutStaticProps, } from '@/layouts/demo/demoLayoutSSG'; import { AMPLITUDE_PAGES } from '@/modules/core/amplitude/amplitude'; import { initializeApollo } from '@/modules/core/apollo/apolloClient'; @@ -40,7 +40,7 @@ const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript- * Only executed on the server side at build time * Necessary when a page has dynamic routes and uses "getStaticProps" */ -export const getStaticPaths: GetStaticPaths = getDemoStaticPaths; +export const getStaticPaths: GetStaticPaths = getDemoLayoutStaticPaths(); /** * Only executed on the server side at build time. @@ -51,7 +51,7 @@ export const getStaticPaths: GetStaticPaths = getDemoSta * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ export const getStaticProps: GetStaticProps = async (props: StaticPropsInput): Promise> => { - const demoStaticProps: GetStaticPropsResult = await getDemoStaticProps(props); + const demoStaticProps: GetStaticPropsResult = await getDemoLayoutStaticProps()(props); if ('props' in demoStaticProps) { const { diff --git a/src/pages/[locale]/public/index.tsx b/src/pages/[locale]/public/index.tsx index 6cb1922d..3f21db67 100644 --- a/src/pages/[locale]/public/index.tsx +++ b/src/pages/[locale]/public/index.tsx @@ -26,7 +26,7 @@ const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript- * Only executed on the server side at build time. * Necessary when a page has dynamic routes and uses "getStaticProps". */ -export const getStaticPaths: GetStaticPaths = getPublicLayoutStaticPaths; +export const getStaticPaths: GetStaticPaths = getPublicLayoutStaticPaths(); /** * Only executed on the server side at build time. @@ -36,7 +36,7 @@ export const getStaticPaths: GetStaticPaths = getPublicL * @see https://github.com/vercel/next.js/discussions/10949#discussioncomment-6884 * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation */ -export const getStaticProps: GetStaticProps = getPublicLayoutStaticProps; +export const getStaticProps: GetStaticProps = getPublicLayoutStaticProps(); /** * SSG pages are first rendered by the server (during static bundling).