From 17bdfca1b960e2788f4e41565e1ebf85f20677ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20W=C3=B8bbe?= Date: Thu, 22 Oct 2020 11:56:17 +0200 Subject: [PATCH] feat(i18n): implement i18n in pages and accommodate/use server side 404 redirects - Make sure a string is sent to API instead of undefined - Make error page look proper --- .../UI/Pages/Category/SingleCategoryPage.tsx | 2 +- pages/[page].tsx | 35 +++++++++++++----- pages/_error.tsx | 37 ++++++++++++++----- pages/category/[category].tsx | 6 ++- pages/category/[category]/[product].tsx | 2 + pages/index.tsx | 17 ++++++++- util/api/calls/getAllProductsByCategory.ts | 2 +- util/api/calls/getSingleCategoryBySlug.ts | 4 +- util/api/calls/getSingleProductFromSlug.ts | 2 +- util/generateProductParamsArr.ts | 4 +- 10 files changed, 84 insertions(+), 27 deletions(-) diff --git a/components/UI/Pages/Category/SingleCategoryPage.tsx b/components/UI/Pages/Category/SingleCategoryPage.tsx index 1d2fa03..3e2c595 100644 --- a/components/UI/Pages/Category/SingleCategoryPage.tsx +++ b/components/UI/Pages/Category/SingleCategoryPage.tsx @@ -31,7 +31,7 @@ const SingleCategoryPage: React.FC = (props) => { component={MUI.Paper} className={classes.paper}> diff --git a/pages/[page].tsx b/pages/[page].tsx index aa8e3a8..cfdaf69 100644 --- a/pages/[page].tsx +++ b/pages/[page].tsx @@ -9,19 +9,24 @@ import routes from '@util/api/queries/allRoutes' import { CONSTANTS, ui } from '@util/settings' import { APIRoute } from 'cms/APIRoute' import groq from 'groq' -import { GetStaticPaths, GetStaticProps, InferGetStaticPropsType } from 'next' +import { + GetStaticProps, + GetStaticPropsContext, + InferGetStaticPropsType +} from 'next' import { NextSeo } from 'next-seo' import { useRouter } from 'next/router' import { PageProps } from 'PageProps' import { useEffect, useState } from 'react' -interface ICustomPageProps extends PageProps { +interface ICustomPageProps extends PageProps, GetStaticPropsContext { currentRoute: APIRoute | null - preview?: boolean - previewData?: Record } -export const getStaticPaths: GetStaticPaths = async () => { +// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types +export const getStaticPaths = async (hmm: unknown) => { + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions + console.info(`GetStaticPathsObj: ${hmm}`) const sanityRoutes: Array<{ slug: { current: string } }> = await getClient( false ).fetch(routes) @@ -29,9 +34,14 @@ export const getStaticPaths: GetStaticPaths = async () => { const routeParams: { params: { page: string } }[] = [] sanityRoutes.forEach((route) => - routeParams.push({ params: { page: `/${route.slug.current}` } }) + routeParams.push({ + params: { page: `/${route.slug.current}` } + }) ) + // eslint-disable-next-line no-console + console.dir(routeParams) + return { paths: !routeParams[0] ? [{ params: { page: 'REDIRECT' } }] : routeParams, fallback: true @@ -40,7 +50,8 @@ export const getStaticPaths: GetStaticPaths = async () => { export const getStaticProps: GetStaticProps = async (ctx) => { const { preview, params } = ctx - + // eslint-disable-next-line no-console + console.log(ctx) const config = await getSanityConfig() const page = params && typeof params.page === 'string' ? params.page : '' @@ -49,14 +60,20 @@ export const getStaticProps: GetStaticProps = async (ctx) => { pageSlug: page }) + if (!fetchedRoute || !fetchedRoute._id) { + return { + unstable_notFound: true + } + } + return { props: { ...config, preview: Boolean(preview), - currentRoute: fetchedRoute || null, + currentRoute: fetchedRoute, ...ctx }, - revalidate: 1 + revalidate: 10 } } diff --git a/pages/_error.tsx b/pages/_error.tsx index c161e26..6179585 100644 --- a/pages/_error.tsx +++ b/pages/_error.tsx @@ -1,22 +1,39 @@ import { PageAnimation } from '@components/UI' import * as MUI from '@material-ui/core' +import getSanityConfig from '@util/api/calls/getSanityConfig' +import { AnimatePresence } from 'framer-motion' +import { NextPage } from 'next' +import { PageProps } from 'PageProps' -interface IErrorProps { - statusCode: string | undefined +interface IErrorProps extends PageProps { + statusCode: number | undefined } -const Error: React.FC = (props) => { +const Error: NextPage = (props) => { const { statusCode } = props return ( - - - {statusCode - ? `An error occurred on the server: ${statusCode}` - : `An error occurred on the client`} - - + + + + {statusCode + ? `An error occurred on the server: ${statusCode}` + : `An error occurred on the client`} + + + ) } +Error.getInitialProps = async (ctx) => { + const config = await getSanityConfig() + // console.log(ctx) + + return { + ...config, + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + statusCode: ctx.res?.statusCode + } +} + export default Error diff --git a/pages/category/[category].tsx b/pages/category/[category].tsx index c26fd3b..b34b582 100644 --- a/pages/category/[category].tsx +++ b/pages/category/[category].tsx @@ -23,7 +23,9 @@ export const getStaticPaths: GetStaticPaths = async () => { const categoriesArr: { params: { category: string } }[] = [] categories.forEach((category) => { - categoriesArr.push({ params: { category: category.url.current } }) + categoriesArr.push({ + params: { category: category?.url?.current || 'UNDEFINED' } + }) }) return { @@ -48,6 +50,8 @@ export const getStaticProps: GetStaticProps = async (ctx) => { const config = await getSanityConfig() + const error = 'I18n is not enabled in `next.config.js`' + + /** + * Get translation files based on current locale + * + * `translation` is handled like an export default js module + * To access keys in the file, use object notation + */ + const translation = resolveTranslationFiles({ + locale: ctx.locale || error, + locales: ctx.locales || [error], + namespaces: ['homePage', 'test'] + }) + return { - props: { ...ctx, ...config }, + props: { ...ctx, ...config, translation }, revalidate: 3600 } } diff --git a/util/api/calls/getAllProductsByCategory.ts b/util/api/calls/getAllProductsByCategory.ts index 48a7d81..46d6815 100644 --- a/util/api/calls/getAllProductsByCategory.ts +++ b/util/api/calls/getAllProductsByCategory.ts @@ -8,7 +8,7 @@ import productsByCategory from '../queries/allProductsByCategory' */ async function getProductsByCategory(id: string): Promise { const data: Product[] = await getClient(false).fetch(productsByCategory, { - id + id: `${id}` }) return data diff --git a/util/api/calls/getSingleCategoryBySlug.ts b/util/api/calls/getSingleCategoryBySlug.ts index aace636..9a9b159 100644 --- a/util/api/calls/getSingleCategoryBySlug.ts +++ b/util/api/calls/getSingleCategoryBySlug.ts @@ -7,7 +7,9 @@ import categoryBySlug from '../queries/singleCategoryBySlug' * @returns {Promise} The category provided by slug */ async function getCategoryBySlug(slug: string): Promise { - const data: Category = await getClient(false).fetch(categoryBySlug, { slug }) + const data: Category = await getClient(false).fetch(categoryBySlug, { + slug: `${slug}` + }) return data } diff --git a/util/api/calls/getSingleProductFromSlug.ts b/util/api/calls/getSingleProductFromSlug.ts index e7887ad..34eca5b 100644 --- a/util/api/calls/getSingleProductFromSlug.ts +++ b/util/api/calls/getSingleProductFromSlug.ts @@ -8,7 +8,7 @@ import singleProductFromSlug from '../queries/singleProductBySlug' */ async function getSingleProductBySlug(slug: string): Promise { const data: Product = await getClient(false).fetch(singleProductFromSlug, { - slug + slug: `${slug}` }) return data diff --git a/util/generateProductParamsArr.ts b/util/generateProductParamsArr.ts index 0b07dc5..5f8175a 100644 --- a/util/generateProductParamsArr.ts +++ b/util/generateProductParamsArr.ts @@ -38,8 +38,8 @@ async function generateProductParamsArr(): Promise { if (productInCategory) paramsArr.push({ params: { - category: cat.url.current, - product: prod.url.current + category: cat.url?.current, + product: prod.url?.current } }) })