From 8233de7c5355f502eb335d00682c42e2f8dde456 Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Wed, 2 Feb 2022 12:31:45 +0100 Subject: fix: handle getStaticPaths fallback I had errors with next build because of fallback. I need to return early if the path does not exists, if not Next complains about undefined variables. I don't think it was related but I also fix the paths format in getStaticPaths, I forgot the params object in some dynamic routes. --- src/pages/article/[slug].tsx | 52 +++++++++++++++++++++++------------------ src/pages/sujet/[slug].tsx | 9 +++++-- src/pages/thematique/[slug].tsx | 7 +++++- src/ts/types/app.ts | 4 ++++ src/utils/helpers/format.ts | 12 ++++++++++ 5 files changed, 58 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/pages/article/[slug].tsx b/src/pages/article/[slug].tsx index d0ea68a..d00d939 100644 --- a/src/pages/article/[slug].tsx +++ b/src/pages/article/[slug].tsx @@ -4,14 +4,17 @@ import { getLayout } from '@components/Layouts/Layout'; import PostFooter from '@components/PostFooter/PostFooter'; import PostHeader from '@components/PostHeader/PostHeader'; import Sidebar from '@components/Sidebar/Sidebar'; +import Spinner from '@components/Spinner/Spinner'; import { Sharing, ToC } from '@components/Widgets'; import { getAllPostsSlug, getPostBySlug } from '@services/graphql/queries'; import styles from '@styles/pages/Page.module.scss'; import { NextPageWithLayout } from '@ts/types/app'; import { ArticleMeta, ArticleProps } from '@ts/types/articles'; import { settings } from '@utils/config'; +import { getFormattedPaths } from '@utils/helpers/format'; import { loadTranslation } from '@utils/helpers/i18n'; import { addPrismClasses, translateCopyButton } from '@utils/helpers/prism'; +import { usePrismTheme } from '@utils/providers/prism'; import { GetStaticPaths, GetStaticProps, GetStaticPropsContext } from 'next'; import Head from 'next/head'; import { useRouter } from 'next/router'; @@ -21,9 +24,32 @@ import { useEffect } from 'react'; import { useIntl } from 'react-intl'; import { Blog, BlogPosting, Graph, WebPage } from 'schema-dts'; import '@utils/plugins/prism-color-scheme'; -import { usePrismTheme } from '@utils/providers/prism'; const SingleArticle: NextPageWithLayout = ({ post }) => { + const intl = useIntl(); + const router = useRouter(); + const locale = router.locale ? router.locale : settings.locales.defaultLocale; + + useEffect(() => { + addPrismClasses(); + Prism.highlightAll(); + }); + + useEffect(() => { + translateCopyButton(locale, intl); + }, [intl, locale]); + + const { setCodeBlocks } = usePrismTheme(); + + useEffect(() => { + const allPre: NodeListOf = document.querySelectorAll( + 'pre[data-prismjs-color-scheme' + ); + setCodeBlocks(allPre); + }, [setCodeBlocks, router.asPath]); + + if (router.isFallback) return ; + const { author, comments, @@ -48,29 +74,8 @@ const SingleArticle: NextPageWithLayout = ({ post }) => { wordsCount: info.wordsCount, }; - const intl = useIntl(); - const router = useRouter(); - const locale = router.locale ? router.locale : settings.locales.defaultLocale; const articleUrl = `${settings.url}${router.asPath}`; - useEffect(() => { - addPrismClasses(); - Prism.highlightAll(); - }); - - useEffect(() => { - translateCopyButton(locale, intl); - }, [intl, locale]); - - const { setCodeBlocks } = usePrismTheme(); - - useEffect(() => { - const allPre: NodeListOf = document.querySelectorAll( - 'pre[data-prismjs-color-scheme' - ); - setCodeBlocks(allPre); - }, [setCodeBlocks, router.asPath]); - const webpageSchema: WebPage = { '@id': `${articleUrl}`, '@type': 'WebPage', @@ -192,9 +197,10 @@ export const getStaticProps: GetStaticProps = async ( export const getStaticPaths: GetStaticPaths = async () => { const allSlugs = await getAllPostsSlug(); + const paths = getFormattedPaths(allSlugs); return { - paths: allSlugs.map((post) => `/article/${post.slug}`), + paths, fallback: true, }; }; diff --git a/src/pages/sujet/[slug].tsx b/src/pages/sujet/[slug].tsx index 3ccacbb..ca7d7cd 100644 --- a/src/pages/sujet/[slug].tsx +++ b/src/pages/sujet/[slug].tsx @@ -2,6 +2,7 @@ import { getLayout } from '@components/Layouts/Layout'; import PostHeader from '@components/PostHeader/PostHeader'; import PostPreview from '@components/PostPreview/PostPreview'; import Sidebar from '@components/Sidebar/Sidebar'; +import Spinner from '@components/Spinner/Spinner'; import { RelatedThematics, ToC, TopicsList } from '@components/Widgets'; import { getAllTopicsSlug, getTopicBySlug } from '@services/graphql/queries'; import styles from '@styles/pages/Page.module.scss'; @@ -9,6 +10,7 @@ import { NextPageWithLayout } from '@ts/types/app'; import { ArticleMeta } from '@ts/types/articles'; import { TopicProps, ThematicPreview } from '@ts/types/taxonomies'; import { settings } from '@utils/config'; +import { getFormattedPaths } from '@utils/helpers/format'; import { loadTranslation } from '@utils/helpers/i18n'; import { GetStaticPaths, GetStaticProps, GetStaticPropsContext } from 'next'; import Head from 'next/head'; @@ -23,6 +25,8 @@ const Topic: NextPageWithLayout = ({ topic }) => { const relatedThematics = useRef([]); const router = useRouter(); + if (router.isFallback) return ; + const updateRelatedThematics = (newThematics: ThematicPreview[]) => { newThematics.forEach((thematic) => { const thematicIndex = relatedThematics.current.findIndex( @@ -182,10 +186,11 @@ export const getStaticProps: GetStaticProps = async ( }; export const getStaticPaths: GetStaticPaths = async () => { - const allSlugs = await getAllTopicsSlug(); + const allTopics = await getAllTopicsSlug(); + const paths = getFormattedPaths(allTopics); return { - paths: allSlugs.map((post) => `/sujet/${post.slug}`), + paths, fallback: true, }; }; diff --git a/src/pages/thematique/[slug].tsx b/src/pages/thematique/[slug].tsx index dbef25b..df7ff1a 100644 --- a/src/pages/thematique/[slug].tsx +++ b/src/pages/thematique/[slug].tsx @@ -2,6 +2,7 @@ import { getLayout } from '@components/Layouts/Layout'; import PostHeader from '@components/PostHeader/PostHeader'; import PostPreview from '@components/PostPreview/PostPreview'; import Sidebar from '@components/Sidebar/Sidebar'; +import Spinner from '@components/Spinner/Spinner'; import { RelatedTopics, ThematicsList, ToC } from '@components/Widgets'; import { getAllThematicsSlug, @@ -12,6 +13,7 @@ import { NextPageWithLayout } from '@ts/types/app'; import { ArticleMeta } from '@ts/types/articles'; import { TopicPreview, ThematicProps } from '@ts/types/taxonomies'; import { settings } from '@utils/config'; +import { getFormattedPaths } from '@utils/helpers/format'; import { loadTranslation } from '@utils/helpers/i18n'; import { GetStaticPaths, GetStaticProps, GetStaticPropsContext } from 'next'; import Head from 'next/head'; @@ -26,6 +28,8 @@ const Thematic: NextPageWithLayout = ({ thematic }) => { const relatedTopics = useRef([]); const router = useRouter(); + if (router.isFallback) return ; + const updateRelatedTopics = (newTopics: TopicPreview[]) => { newTopics.forEach((topic) => { const topicIndex = relatedTopics.current.findIndex( @@ -173,9 +177,10 @@ export const getStaticProps: GetStaticProps = async ( export const getStaticPaths: GetStaticPaths = async () => { const allSlugs = await getAllThematicsSlug(); + const paths = getFormattedPaths(allSlugs); return { - paths: allSlugs.map((post) => `/thematique/${post.slug}`), + paths, fallback: true, }; }; diff --git a/src/ts/types/app.ts b/src/ts/types/app.ts index 636aeed..2c9a291 100644 --- a/src/ts/types/app.ts +++ b/src/ts/types/app.ts @@ -100,6 +100,10 @@ export type PageInfo = { total: number; }; +export type ParamsSlug = { + params: { slug: string }; +}; + export type Project = { cover?: string; id: string; diff --git a/src/utils/helpers/format.ts b/src/utils/helpers/format.ts index e45a6a0..817daaf 100644 --- a/src/utils/helpers/format.ts +++ b/src/utils/helpers/format.ts @@ -1,3 +1,4 @@ +import { ParamsSlug, Slug } from '@ts/types/app'; import { Article, ArticlePreview, @@ -283,3 +284,14 @@ export const getFormattedDate = (date: string, locale: string) => { return new Date(date).toLocaleDateString(locale, dateOptions); }; + +/** + * Convert an array of slugs to an array of params with slug. + * @param {Slug} array - An array of object with slug. + * @returns {ParamsSlug} An array of params with slug. + */ +export const getFormattedPaths = (array: Slug[]): ParamsSlug[] => { + return array.map((object) => { + return { params: { slug: object.slug } }; + }); +}; -- cgit v1.2.3