You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
118 lines
3.1 KiB
118 lines
3.1 KiB
2 years ago
|
import ErrorPage from "next/error"
|
||
|
import { getPageData, fetchAPI, getGlobalData } from "utils/api"
|
||
|
import Sections from "@/components/sections"
|
||
|
import Seo from "@/components/elements/seo"
|
||
|
import { useRouter } from "next/router"
|
||
|
import Layout from "@/components/layout"
|
||
|
import { getLocalizedPaths } from "utils/localize"
|
||
|
|
||
|
// The file is called [[...slug]].js because we're using Next's
|
||
|
// optional catch all routes feature. See the related docs:
|
||
|
// https://nextjs.org/docs/routing/dynamic-routes#optional-catch-all-routes
|
||
|
|
||
|
const DynamicPage = ({ sections, metadata, preview, global, pageContext }) => {
|
||
|
const router = useRouter()
|
||
|
|
||
|
// Check if the required data was provided
|
||
|
if (!router.isFallback && !sections?.length) {
|
||
|
return <ErrorPage statusCode={404} />
|
||
|
}
|
||
|
|
||
|
// Loading screen (only possible in preview mode)
|
||
|
if (router.isFallback) {
|
||
|
return <div className="container">Loading...</div>
|
||
|
}
|
||
|
|
||
|
// Merge default site SEO settings with page specific SEO settings
|
||
|
if (metadata.shareImage?.data == null) {
|
||
|
delete metadata.shareImage
|
||
|
}
|
||
|
const metadataWithDefaults = {
|
||
|
...global.attributes.metadata,
|
||
|
...metadata,
|
||
|
}
|
||
|
|
||
|
return (
|
||
|
<Layout global={global} pageContext={pageContext}>
|
||
|
{/* Add meta tags for SEO*/}
|
||
|
<Seo metadata={metadataWithDefaults} />
|
||
|
{/* Display content sections */}
|
||
|
<Sections sections={sections} preview={preview} />
|
||
|
</Layout>
|
||
|
)
|
||
|
}
|
||
|
|
||
|
export async function getStaticPaths(context) {
|
||
|
// Get all pages from Strapi
|
||
|
const pages = await context.locales.reduce(
|
||
|
async (currentPagesPromise, locale) => {
|
||
|
const currentPages = await currentPagesPromise
|
||
|
const localePages = await fetchAPI("/pages", {
|
||
|
locale,
|
||
|
fields: ["slug", "locale"],
|
||
|
})
|
||
|
return [...currentPages, ...localePages.data]
|
||
|
},
|
||
|
Promise.resolve([])
|
||
|
)
|
||
|
|
||
|
const paths = pages.map((page) => {
|
||
|
const { slug, locale } = page.attributes
|
||
|
// Decompose the slug that was saved in Strapi
|
||
|
const slugArray = !slug ? false : slug.split("/")
|
||
|
|
||
|
return {
|
||
|
params: { slug: slugArray },
|
||
|
// Specify the locale to render
|
||
|
locale,
|
||
|
}
|
||
|
})
|
||
|
|
||
|
return { paths, fallback: true }
|
||
|
}
|
||
|
|
||
|
export async function getStaticProps(context) {
|
||
|
const { params, locale, locales, defaultLocale, preview = null } = context
|
||
|
|
||
|
const globalLocale = await getGlobalData(locale)
|
||
|
// Fetch pages. Include drafts if preview mode is on
|
||
|
const pageData = await getPageData({
|
||
|
slug: (!params.slug ? [""] : params.slug).join("/"),
|
||
|
locale,
|
||
|
preview,
|
||
|
})
|
||
|
|
||
|
if (pageData == null) {
|
||
|
// Giving the page no props will trigger a 404 page
|
||
|
return { props: {} }
|
||
|
}
|
||
|
|
||
|
// We have the required page data, pass it to the page component
|
||
|
const { contentSections, metadata, localizations, slug } = pageData.attributes
|
||
|
|
||
|
const pageContext = {
|
||
|
locale,
|
||
|
locales,
|
||
|
defaultLocale,
|
||
|
slug,
|
||
|
localizations,
|
||
|
}
|
||
|
|
||
|
const localizedPaths = getLocalizedPaths(pageContext)
|
||
|
|
||
|
return {
|
||
|
props: {
|
||
|
preview,
|
||
|
sections: contentSections,
|
||
|
metadata,
|
||
|
global: globalLocale.data,
|
||
|
pageContext: {
|
||
|
...pageContext,
|
||
|
localizedPaths,
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
}
|
||
|
|
||
|
export default DynamicPage
|