diff options
| author | Armand Philippot <git@armandphilippot.com> | 2023-12-01 19:34:58 +0100 |
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2023-12-04 19:00:04 +0100 |
| commit | 53b63ac27c2275262db9a04be02210a3287aa71d (patch) | |
| tree | 814968e10cad25e1b34ab251de42ac5ecb82b346 /src/pages/blog | |
| parent | 11e3ee75fcab0ab54b2bc1713a402c5cc3070c2d (diff) | |
refactor(pages): refine Blog pages
* replace usePostsList with useArticlesList to keep names coherent
* remove useIsMounted hook
* rewrite useRedirection hook
* add redirect in getStaticProps to avoid unecessary fetching
* move Pagination component in a noscript tag
* use hooks to refresh thematics and topics lists
* complete Cypress tests
Diffstat (limited to 'src/pages/blog')
| -rw-r--r-- | src/pages/blog/index.tsx | 305 | ||||
| -rw-r--r-- | src/pages/blog/page/[number].tsx | 334 |
2 files changed, 392 insertions, 247 deletions
diff --git a/src/pages/blog/index.tsx b/src/pages/blog/index.tsx index 12bc03e..df25cd2 100644 --- a/src/pages/blog/index.tsx +++ b/src/pages/blog/index.tsx @@ -1,9 +1,8 @@ /* eslint-disable max-statements */ import type { GetStaticProps } from 'next'; import Head from 'next/head'; -import { useRouter } from 'next/router'; import Script from 'next/script'; -import { useCallback, useRef } from 'react'; +import { useCallback } from 'react'; import { useIntl } from 'react-intl'; import { getLayout, @@ -18,11 +17,11 @@ import { PageHeader, PageBody, PageSidebar, + Spinner, } from '../../components'; import { convertWPThematicPreviewToPageLink, convertWPTopicPreviewToPageLink, - fetchPostsCount, fetchPostsList, fetchThematicsCount, fetchThematicsList, @@ -47,71 +46,30 @@ import { getWebPageSchema, } from '../../utils/helpers'; import { loadTranslation, type Messages } from '../../utils/helpers/server'; -import { useBreadcrumb, useIsMounted, usePostsList } from '../../utils/hooks'; +import { + useArticlesList, + useBreadcrumb, + useThematicsList, + useTopicsList, +} from '../../utils/hooks'; + +const renderPaginationLink: RenderPaginationLink = (pageNum) => + `${ROUTES.BLOG}/page/${pageNum}`; type BlogPageProps = { - posts: GraphQLConnection<WPPostPreview>; - thematicsList: WPThematicPreview[]; - topicsList: WPTopicPreview[]; - totalArticles: number; + data: { + posts: GraphQLConnection<WPPostPreview>; + thematics: GraphQLConnection<WPThematicPreview>; + topics: GraphQLConnection<WPTopicPreview>; + }; translation: Messages; }; /** * Blog index page. */ -const BlogPage: NextPageWithLayout<BlogPageProps> = ({ - posts, - thematicsList, - topicsList, - totalArticles, -}) => { +const BlogPage: NextPageWithLayout<BlogPageProps> = ({ data }) => { const intl = useIntl(); - const title = intl.formatMessage({ - defaultMessage: 'Blog', - description: 'BlogPage: page title', - id: '7TbbIk', - }); - const { items: breadcrumbItems, schema: breadcrumbSchema } = useBreadcrumb({ - title, - url: ROUTES.BLOG, - }); - const postsListRef = useRef<HTMLDivElement>(null); - const isMounted = useIsMounted(postsListRef); - const { asPath } = useRouter(); - const page = { - title: intl.formatMessage( - { - defaultMessage: 'Blog: development, open source - {websiteName}', - description: 'BlogPage: SEO - Page title', - id: '+Y+tLK', - }, - { websiteName: CONFIG.name } - ), - url: `${CONFIG.url}${asPath}`, - }; - const pageDescription = intl.formatMessage( - { - defaultMessage: - "Discover {websiteName}'s writings. He talks about web development, Linux and open source mostly.", - description: 'BlogPage: SEO - Meta description', - id: '18h/t0', - }, - { websiteName: CONFIG.name } - ); - const webpageSchema = getWebPageSchema({ - description: pageDescription, - locale: CONFIG.locales.defaultLocale, - slug: asPath, - title, - }); - const blogSchema = getBlogSchema({ - isSinglePage: false, - locale: CONFIG.locales.defaultLocale, - slug: asPath, - }); - const schemaJsonLd = getSchemaJson([webpageSchema, blogSchema]); - const { articles, error, @@ -121,27 +79,101 @@ const BlogPage: NextPageWithLayout<BlogPageProps> = ({ isRefreshing, hasNextPage, loadMore, - } = usePostsList({ - fallback: [posts], - fetcher: fetchPostsList, + } = useArticlesList({ + fallback: [data.posts], perPage: CONFIG.postsPerPage, }); + const { isLoading: areThematicsLoading, thematics } = useThematicsList({ + fallback: data.thematics, + input: { first: data.thematics.pageInfo.total }, + }); + const { isLoading: areTopicsLoading, topics } = useTopicsList({ + fallback: data.topics, + input: { first: data.topics.pageInfo.total }, + }); - const thematicsListTitle = intl.formatMessage({ - defaultMessage: 'Thematics', - description: 'BlogPage: thematics list widget title', - id: 'HriY57', + const messages = { + loading: { + thematicsList: intl.formatMessage({ + defaultMessage: 'Thematics are loading...', + description: 'BlogPage: loading thematics message', + id: 'y37FuH', + }), + topicsList: intl.formatMessage({ + defaultMessage: 'Topics are loading...', + description: 'BlogPage: loading topics message', + id: 'OsclKU', + }), + }, + pageTitle: intl.formatMessage({ + defaultMessage: 'Blog', + description: 'BlogPage: page title', + id: '7TbbIk', + }), + pagination: { + noJS: intl.formatMessage({ + defaultMessage: + "You can't load more articles without Javascript, please use the pagination instead.", + description: 'BlogPage: pagination no script message', + id: 'ZMES/E', + }), + title: intl.formatMessage({ + defaultMessage: 'Pagination', + description: 'BlogPage: pagination accessible name', + id: 'AXe1Iz', + }), + }, + seo: { + metaDesc: intl.formatMessage( + { + defaultMessage: + "Discover {websiteName}'s writings. He talks about web development, Linux and open source mostly.", + description: 'BlogPage: SEO - Meta description', + id: '18h/t0', + }, + { websiteName: CONFIG.name } + ), + title: intl.formatMessage( + { + defaultMessage: 'Blog: development, open source - {websiteName}', + description: 'BlogPage: SEO - Page title', + id: '+Y+tLK', + }, + { websiteName: CONFIG.name } + ), + }, + widgets: { + thematicsListTitle: intl.formatMessage({ + defaultMessage: 'Thematics', + description: 'BlogPage: thematics list widget title', + id: 'HriY57', + }), + topicsListTitle: intl.formatMessage({ + defaultMessage: 'Topics', + description: 'BlogPage: topics list widget title', + id: '2D9tB5', + }), + }, + }; + + const { items: breadcrumbItems, schema: breadcrumbSchema } = useBreadcrumb({ + title: messages.pageTitle, + url: ROUTES.BLOG, }); - const topicsListTitle = intl.formatMessage({ - defaultMessage: 'Topics', - description: 'BlogPage: topics list widget title', - id: '2D9tB5', + const webpageSchema = getWebPageSchema({ + description: messages.seo.metaDesc, + locale: CONFIG.locales.defaultLocale, + slug: ROUTES.BLOG, + title: messages.pageTitle, }); - const renderPaginationLink: RenderPaginationLink = useCallback( - (pageNum) => `${ROUTES.BLOG}/page/${pageNum}`, - [] - ); + const blogSchema = getBlogSchema({ + isSinglePage: false, + locale: CONFIG.locales.defaultLocale, + slug: ROUTES.BLOG, + }); + const schemaJsonLd = getSchemaJson([webpageSchema, blogSchema]); + const renderPaginationLabel: RenderPaginationItemAriaLabel = useCallback( ({ kind, pageNumber: number, isCurrentPage }) => { switch (kind) { @@ -187,27 +219,19 @@ const BlogPage: NextPageWithLayout<BlogPageProps> = ({ [intl] ); - const paginationAriaLabel = intl.formatMessage({ - defaultMessage: 'Pagination', - description: 'BlogPage: pagination accessible name', - id: 'AXe1Iz', - }); - - const blogArticles = articles?.flatMap((p) => - p.edges.map((edge) => edge.node) - ); + const pageUrl = `${CONFIG.url}${ROUTES.BLOG}`; return ( <Page breadcrumbs={breadcrumbItems} isBodyLastChild> <Head> - <title>{page.title}</title> + <title>{messages.seo.title}</title> {/*eslint-disable-next-line react/jsx-no-literals -- Name allowed */} - <meta name="description" content={pageDescription} /> - <meta property="og:url" content={page.url} /> + <meta name="description" content={messages.seo.metaDesc} /> + <meta property="og:url" content={pageUrl} /> {/*eslint-disable-next-line react/jsx-no-literals -- Content allowed */} <meta property="og:type" content="website" /> - <meta property="og:title" content={title} /> - <meta property="og:description" content={pageDescription} /> + <meta property="og:title" content={messages.pageTitle} /> + <meta property="og:description" content={messages.seo.metaDesc} /> </Head> <Script // eslint-disable-next-line react/jsx-no-literals -- Id allowed @@ -222,30 +246,24 @@ const BlogPage: NextPageWithLayout<BlogPageProps> = ({ id="schema-breadcrumb" type="application/ld+json" /> - <PageHeader heading={title} meta={{ total: totalArticles }} /> - <PageBody className={styles.body}> - {blogArticles ? ( + <PageHeader + heading={messages.pageTitle} + meta={{ total: data.posts.pageInfo.total }} + /> + <PageBody> + {articles ? ( <PostsList - className={styles.list} + className={styles['posts-list']} firstNewResult={firstNewResultIndex} isLoading={isLoading || isLoadingMore || isRefreshing} - onLoadMore={hasNextPage && isMounted ? loadMore : undefined} - posts={getPostsWithUrl(blogArticles)} - ref={postsListRef} + onLoadMore={hasNextPage ? loadMore : undefined} + posts={getPostsWithUrl( + articles.flatMap((page) => page.edges.map((edge) => edge.node)) + )} sortByYear - total={isMounted ? totalArticles : undefined} + total={data.posts.pageInfo.total} /> ) : null} - {isMounted ? null : ( - <Pagination - aria-label={paginationAriaLabel} - current={1} - isCentered - renderItemAriaLabel={renderPaginationLabel} - renderLink={renderPaginationLink} - total={totalArticles} - /> - )} {error ? ( <Notice // eslint-disable-next-line react/jsx-no-literals -- Kind allowed @@ -258,28 +276,53 @@ const BlogPage: NextPageWithLayout<BlogPageProps> = ({ })} </Notice> ) : null} + <noscript> + <Notice + // eslint-disable-next-line react/jsx-no-literals + kind="info" + > + {messages.pagination.noJS} + </Notice> + <Pagination + aria-label={messages.pagination.title} + className={styles.pagination} + current={1} + isCentered + renderItemAriaLabel={renderPaginationLabel} + renderLink={renderPaginationLink} + total={data.posts.pageInfo.total} + /> + </noscript> </PageBody> <PageSidebar> - <LinksWidget - heading={ - <Heading isFake level={3}> - {thematicsListTitle} - </Heading> - } - items={getLinksItemData( - thematicsList.map(convertWPThematicPreviewToPageLink) - )} - /> - <LinksWidget - heading={ - <Heading isFake level={3}> - {topicsListTitle} - </Heading> - } - items={getLinksItemData( - topicsList.map(convertWPTopicPreviewToPageLink) - )} - /> + {areThematicsLoading ? ( + <Spinner>{messages.loading.thematicsList}</Spinner> + ) : ( + <LinksWidget + heading={ + <Heading level={2}>{messages.widgets.thematicsListTitle}</Heading> + } + items={getLinksItemData( + thematics.edges.map((edge) => + convertWPThematicPreviewToPageLink(edge.node) + ) + )} + /> + )} + {areTopicsLoading ? ( + <Spinner>{messages.loading.topicsList}</Spinner> + ) : ( + <LinksWidget + heading={ + <Heading level={2}>{messages.widgets.topicsListTitle}</Heading> + } + items={getLinksItemData( + topics.edges.map((edge) => + convertWPTopicPreviewToPageLink(edge.node) + ) + )} + /> + )} </PageSidebar> </Page> ); @@ -291,7 +334,6 @@ export const getStaticProps: GetStaticProps<BlogPageProps> = async ({ locale, }) => { const posts = await fetchPostsList({ first: CONFIG.postsPerPage }); - const totalArticles = await fetchPostsCount(); const totalThematics = await fetchThematicsCount(); const thematics = await fetchThematicsList({ first: totalThematics }); const totalTopics = await fetchTopicsCount(); @@ -300,10 +342,11 @@ export const getStaticProps: GetStaticProps<BlogPageProps> = async ({ return { props: { - posts: JSON.parse(JSON.stringify(posts)), - thematicsList: thematics.edges.map((edge) => edge.node), - topicsList: topics.edges.map((edge) => edge.node), - totalArticles, + data: { + posts: JSON.parse(JSON.stringify(posts)), + thematics, + topics, + }, translation, }, }; diff --git a/src/pages/blog/page/[number].tsx b/src/pages/blog/page/[number].tsx index 35d4bad..ec465c2 100644 --- a/src/pages/blog/page/[number].tsx +++ b/src/pages/blog/page/[number].tsx @@ -18,6 +18,9 @@ import { PageHeader, PageBody, PageSidebar, + Spinner, + Notice, + LoadingPage, } from '../../../components'; import { convertWPThematicPreviewToPageLink, @@ -30,9 +33,12 @@ import { fetchTopicsCount, fetchTopicsList, } from '../../../services/graphql'; +import styles from '../../../styles/pages/blog.module.scss'; import type { GraphQLConnection, + Maybe, NextPageWithLayout, + Nullable, WPPostPreview, WPThematicPreview, WPTopicPreview, @@ -48,17 +54,24 @@ import { } from '../../../utils/helpers'; import { loadTranslation, type Messages } from '../../../utils/helpers/server'; import { + useArticlesList, useBreadcrumb, - usePostsList, useRedirection, + useThematicsList, + useTopicsList, } from '../../../utils/hooks'; +const renderPaginationLink: RenderPaginationLink = (pageNum) => + `${ROUTES.BLOG}/page/${pageNum}`; + type BlogPageProps = { + data: { + posts: GraphQLConnection<WPPostPreview>; + thematics: GraphQLConnection<WPThematicPreview>; + topics: GraphQLConnection<WPTopicPreview>; + }; + lastCursor: Maybe<Nullable<string>>; pageNumber: number; - posts: GraphQLConnection<WPPostPreview>; - thematicsList: WPThematicPreview[]; - topicsList: WPTopicPreview[]; - totalArticles: number; translation: Messages; }; @@ -66,86 +79,129 @@ type BlogPageProps = { * Blog index page. */ const BlogPage: NextPageWithLayout<BlogPageProps> = ({ + data, + lastCursor, pageNumber, - posts, - thematicsList, - topicsList, - totalArticles, }) => { useRedirection({ - query: { param: 'number', value: '1' }, - redirectTo: ROUTES.BLOG, + isReplacing: true, + to: ROUTES.BLOG, + whenPathMatches: (path) => path === `${ROUTES.BLOG}/page/1`, }); - const { articles } = usePostsList({ - fallback: [posts], - fetcher: fetchPostsList, + const intl = useIntl(); + const { isFallback } = useRouter(); + const { + articles, + error, + firstNewResultIndex, + isLoading, + isLoadingMore, + isRefreshing, + hasNextPage, + loadMore, + } = useArticlesList({ + after: lastCursor, + fallback: [data.posts], perPage: CONFIG.postsPerPage, }); - const intl = useIntl(); - const title = intl.formatMessage({ - defaultMessage: 'Blog', - description: 'BlogPage: page title', - id: '7TbbIk', + const { isLoading: areThematicsLoading, thematics } = useThematicsList({ + fallback: data.thematics, + input: { first: data.thematics.pageInfo.total }, + }); + const { isLoading: areTopicsLoading, topics } = useTopicsList({ + fallback: data.topics, + input: { first: data.topics.pageInfo.total }, }); - const pageNumberTitle = intl.formatMessage( - { - defaultMessage: 'Page {number}', - id: 'zbzlb1', - description: 'BlogPage: page number', + + const messages = { + loading: { + thematicsList: intl.formatMessage({ + defaultMessage: 'Thematics are loading...', + description: 'BlogPage: loading thematics message', + id: 'y37FuH', + }), + topicsList: intl.formatMessage({ + defaultMessage: 'Topics are loading...', + description: 'BlogPage: loading topics message', + id: 'OsclKU', + }), }, - { - number: pageNumber, - } - ); - const pageTitleWithPageNumber = `${title} - ${pageNumberTitle}`; + pageTitle: intl.formatMessage( + { + defaultMessage: 'Blog - Page {number}', + description: 'BlogPage: page title with number', + id: '8xVO3Y', + }, + { + number: pageNumber, + } + ), + pagination: { + noJS: intl.formatMessage({ + defaultMessage: + "You can't load more articles without Javascript, please use the pagination instead.", + description: 'BlogPage: pagination no script message', + id: 'ZMES/E', + }), + title: intl.formatMessage({ + defaultMessage: 'Pagination', + description: 'BlogPage: pagination accessible name', + id: 'AXe1Iz', + }), + }, + seo: { + metaDesc: intl.formatMessage( + { + defaultMessage: + "Discover {websiteName}'s writings. He talks about web development, Linux and open source mostly.", + description: 'BlogPage: SEO - Meta description', + id: '18h/t0', + }, + { websiteName: CONFIG.name } + ), + title: intl.formatMessage( + { + defaultMessage: + 'Blog: development, open source - Page {number} - {websiteName}', + description: 'BlogPage: SEO - Page title', + id: 'dG3sT3', + }, + { number: pageNumber, websiteName: CONFIG.name } + ), + }, + widgets: { + thematicsListTitle: intl.formatMessage({ + defaultMessage: 'Thematics', + description: 'BlogPage: thematics list widget title', + id: 'HriY57', + }), + topicsListTitle: intl.formatMessage({ + defaultMessage: 'Topics', + description: 'BlogPage: topics list widget title', + id: '2D9tB5', + }), + }, + }; + const { items: breadcrumbItems, schema: breadcrumbSchema } = useBreadcrumb({ - title: pageNumberTitle, + title: messages.pageTitle, url: `${ROUTES.BLOG}/page/${pageNumber}`, }); - const { asPath } = useRouter(); - const page = { - title: `${pageTitleWithPageNumber} - ${CONFIG.name}`, - url: `${CONFIG.url}${asPath}`, - }; - const pageDescription = intl.formatMessage( - { - defaultMessage: - "Discover {websiteName}'s writings. He talks about web development, Linux and open source mostly.", - description: 'BlogPage: SEO - Meta description', - id: '18h/t0', - }, - { websiteName: CONFIG.name } - ); const webpageSchema = getWebPageSchema({ - description: pageDescription, + description: messages.seo.metaDesc, locale: CONFIG.locales.defaultLocale, - slug: asPath, - title, + slug: ROUTES.BLOG, + title: messages.pageTitle, }); const blogSchema = getBlogSchema({ isSinglePage: false, locale: CONFIG.locales.defaultLocale, - slug: asPath, + slug: ROUTES.BLOG, }); const schemaJsonLd = getSchemaJson([webpageSchema, blogSchema]); - const thematicsListTitle = intl.formatMessage({ - defaultMessage: 'Thematics', - description: 'BlogPage: thematics list widget title', - id: 'HriY57', - }); - - const topicsListTitle = intl.formatMessage({ - defaultMessage: 'Topics', - description: 'BlogPage: topics list widget title', - id: '2D9tB5', - }); - const renderPaginationLink: RenderPaginationLink = useCallback( - (pageNum) => `${ROUTES.BLOG}/page/${pageNum}`, - [] - ); const renderPaginationLabel: RenderPaginationItemAriaLabel = useCallback( ({ kind, pageNumber: number, isCurrentPage }) => { switch (kind) { @@ -191,27 +247,21 @@ const BlogPage: NextPageWithLayout<BlogPageProps> = ({ [intl] ); - const paginationAriaLabel = intl.formatMessage({ - defaultMessage: 'Pagination', - description: 'BlogPage: pagination accessible name', - id: 'AXe1Iz', - }); + if (isFallback) return <LoadingPage />; - const blogPageArticles = articles?.flatMap((p) => - p.edges.map((edge) => edge.node) - ); + const pageUrl = `${CONFIG.url}${ROUTES.BLOG}`; return ( <Page breadcrumbs={breadcrumbItems} isBodyLastChild> <Head> - <title>{page.title}</title> + <title>{messages.seo.title}</title> {/*eslint-disable-next-line react/jsx-no-literals -- Name allowed */} - <meta name="description" content={pageDescription} /> - <meta property="og:url" content={page.url} /> + <meta name="description" content={messages.seo.metaDesc} /> + <meta property="og:url" content={pageUrl} /> {/*eslint-disable-next-line react/jsx-no-literals -- Content allowed */} <meta property="og:type" content="website" /> - <meta property="og:title" content={pageTitleWithPageNumber} /> - <meta property="og:description" content={pageDescription} /> + <meta property="og:title" content={messages.pageTitle} /> + <meta property="og:description" content={messages.seo.metaDesc} /> </Head> <Script // eslint-disable-next-line react/jsx-no-literals -- Id allowed @@ -227,41 +277,82 @@ const BlogPage: NextPageWithLayout<BlogPageProps> = ({ type="application/ld+json" /> <PageHeader - heading={pageTitleWithPageNumber} - meta={{ total: totalArticles }} + heading={messages.pageTitle} + meta={{ total: data.posts.pageInfo.total }} /> <PageBody> - <PostsList posts={getPostsWithUrl(blogPageArticles ?? [])} sortByYear /> - <Pagination - aria-label={paginationAriaLabel} - current={pageNumber} - isCentered - renderItemAriaLabel={renderPaginationLabel} - renderLink={renderPaginationLink} - total={totalArticles} - /> + {articles ? ( + <PostsList + className={styles['posts-list']} + firstNewResult={firstNewResultIndex} + isLoading={isLoading || isLoadingMore || isRefreshing} + onLoadMore={hasNextPage ? loadMore : undefined} + posts={getPostsWithUrl( + articles.flatMap((page) => page.edges.map((edge) => edge.node)) + )} + sortByYear + total={data.posts.pageInfo.total} + /> + ) : null} + {error ? ( + <Notice + // eslint-disable-next-line react/jsx-no-literals -- Kind allowed + kind="error" + > + {intl.formatMessage({ + defaultMessage: 'Failed to load.', + description: 'BlogPage: failed to load text', + id: 'C/XGkH', + })} + </Notice> + ) : null} + <noscript> + <Notice + // eslint-disable-next-line react/jsx-no-literals + kind="info" + > + {messages.pagination.noJS} + </Notice> + <Pagination + aria-label={messages.pagination.title} + className={styles.pagination} + current={pageNumber} + isCentered + renderItemAriaLabel={renderPaginationLabel} + renderLink={renderPaginationLink} + total={data.posts.pageInfo.total} + /> + </noscript> </PageBody> <PageSidebar> - <LinksWidget - heading={ - <Heading isFake level={3}> - {thematicsListTitle} - </Heading> - } - items={getLinksItemData( - thematicsList.map(convertWPThematicPreviewToPageLink) - )} - /> - <LinksWidget - heading={ - <Heading isFake level={3}> - {topicsListTitle} - </Heading> - } - items={getLinksItemData( - topicsList.map(convertWPTopicPreviewToPageLink) - )} - /> + {areThematicsLoading ? ( + <Spinner>{messages.loading.thematicsList}</Spinner> + ) : ( + <LinksWidget + heading={ + <Heading level={2}>{messages.widgets.thematicsListTitle}</Heading> + } + items={getLinksItemData( + thematics.edges.map((edge) => + convertWPThematicPreviewToPageLink(edge.node) + ) + )} + /> + )} + {areTopicsLoading ? ( + <Spinner>{messages.loading.topicsList}</Spinner> + ) : ( + <LinksWidget + heading={ + <Heading level={2}>{messages.widgets.topicsListTitle}</Heading> + } + items={getLinksItemData( + topics.edges.map((edge) => + convertWPTopicPreviewToPageLink(edge.node) + ) + )} + /> + )} </PageSidebar> </Page> ); @@ -278,14 +369,23 @@ export const getStaticProps: GetStaticProps<BlogPageProps> = async ({ params, }) => { const pageNumber = Number((params as BlogPageParams).number); - const lastCursor = await fetchLastPostCursor( - CONFIG.postsPerPage * pageNumber - ); + + if (pageNumber === 1) + return { + redirect: { + destination: ROUTES.BLOG, + permanent: true, + }, + }; + + const lastCursor = + pageNumber > 1 + ? await fetchLastPostCursor(CONFIG.postsPerPage * (pageNumber - 1)) + : null; const posts = await fetchPostsList({ first: CONFIG.postsPerPage, after: lastCursor, }); - const totalArticles = await fetchPostsCount(); const totalThematics = await fetchThematicsCount(); const thematics = await fetchThematicsList({ first: totalThematics }); const totalTopics = await fetchTopicsCount(); @@ -294,11 +394,13 @@ export const getStaticProps: GetStaticProps<BlogPageProps> = async ({ return { props: { - posts: JSON.parse(JSON.stringify(posts)), + data: { + posts: JSON.parse(JSON.stringify(posts)), + thematics, + topics, + }, + lastCursor, pageNumber, - thematicsList: thematics.edges.map((edge) => edge.node), - topicsList: topics.edges.map((edge) => edge.node), - totalArticles, translation, }, }; @@ -317,7 +419,7 @@ export const getStaticPaths: GetStaticPaths = async () => { return { paths, - fallback: false, + fallback: true, }; }; |
