From a8398e1bdf6825d6925ce2fd8d4806f14a8f55f2 Mon Sep 17 00:00:00 2001 From: Mathias Oterhals Myklebust Date: Fri, 20 Sep 2024 14:35:27 +0200 Subject: [PATCH] fix(sitemap): include root path in sitemap --- src/app/(main)/page.tsx | 8 +++-- src/app/sitemap.ts | 39 ++++++++++++++++------- studio/components/CustomCallToActions.tsx | 4 +-- studio/lib/interfaces/global.ts | 5 +++ studio/lib/queries/document.ts | 5 +++ studio/lib/queries/navigation.ts | 6 +++- 6 files changed, 50 insertions(+), 17 deletions(-) create mode 100644 studio/lib/queries/document.ts diff --git a/src/app/(main)/page.tsx b/src/app/(main)/page.tsx index 302bcb9fb..f22e0228b 100644 --- a/src/app/(main)/page.tsx +++ b/src/app/(main)/page.tsx @@ -6,12 +6,14 @@ import SectionRenderer from "src/utils/renderSection"; import { fetchSeoData, generateMetadataFromSeo } from "src/utils/seo"; import { LinkType } from "studio/lib/interfaces/navigation"; import { PageBuilder } from "studio/lib/interfaces/pages"; -import { LANDING_QUERY } from "studio/lib/queries/navigation"; +import { LANDING_PAGE_REF_QUERY } from "studio/lib/queries/navigation"; import { PAGE_QUERY, SEO_PAGE_QUERY } from "studio/lib/queries/page"; import { loadStudioQuery } from "studio/lib/store"; export async function generateMetadata(): Promise { - const { data: landingId } = await loadStudioQuery(LANDING_QUERY); + const { data: landingId } = await loadStudioQuery( + LANDING_PAGE_REF_QUERY, + ); const seo = await fetchSeoData(SEO_PAGE_QUERY, { id: landingId }); return generateMetadataFromSeo(seo); } @@ -36,7 +38,7 @@ const Home = async () => { const { perspective, isDraftMode } = getDraftModeInfo(); const { data: landingId } = await loadStudioQuery( - LANDING_QUERY, + LANDING_PAGE_REF_QUERY, {}, { perspective }, ); diff --git a/src/app/sitemap.ts b/src/app/sitemap.ts index 1ae16174f..9e0306c88 100644 --- a/src/app/sitemap.ts +++ b/src/app/sitemap.ts @@ -1,25 +1,42 @@ import type { MetadataRoute } from "next"; import { client } from "studio/lib/client"; -import { Slug } from "studio/lib/interfaces/global"; +import { DocumentWithSlug } from "studio/lib/interfaces/global"; +import { PageBuilder } from "studio/lib/interfaces/pages"; +import { DOCUMENTS_WITH_SLUG_QUERY } from "studio/lib/queries/document"; +import { LANDING_PAGE_QUERY } from "studio/lib/queries/navigation"; import { token } from "studio/lib/token"; -interface SitemapDocument { - slug: Slug; - _updatedAt: string; -} - const clientWithToken = client.withConfig({ token }); export const dynamic = "force-dynamic"; export const fetchCache = "default-no-store"; export default async function sitemap(): Promise { - const documents = - await clientWithToken.fetch(`*[defined(slug)]`); - - return documents.map((s) => ({ - url: new URL(s.slug.current, process.env.NEXT_PUBLIC_URL).toString(), + const baseUrl = + process.env.NEXT_PUBLIC_URL !== undefined && + URL.canParse(process.env.NEXT_PUBLIC_URL) + ? new URL(process.env.NEXT_PUBLIC_URL) + : undefined; + if (baseUrl === undefined) { + console.error("Failed to generate sitemap, missing baseUrl"); + return []; + } + const slugDocuments = await clientWithToken.fetch( + DOCUMENTS_WITH_SLUG_QUERY, + ); + const sitemapEntries = slugDocuments.map((s) => ({ + url: new URL(s.slug.current, baseUrl).toString(), lastModified: new Date(s._updatedAt), })); + const landingPage = await clientWithToken.fetch( + LANDING_PAGE_QUERY, + ); + if (landingPage !== null) { + sitemapEntries.push({ + url: baseUrl.toString(), + lastModified: new Date(landingPage._updatedAt), + }); + } + return sitemapEntries; } diff --git a/studio/components/CustomCallToActions.tsx b/studio/components/CustomCallToActions.tsx index 27f56cdbe..13c5c13ee 100644 --- a/studio/components/CustomCallToActions.tsx +++ b/studio/components/CustomCallToActions.tsx @@ -9,7 +9,7 @@ import { } from "sanity"; import { fetchWithToken } from "studio/lib/fetchWithToken"; -import { LANDING_QUERY } from "studio/lib/queries/navigation"; +import { LANDING_PAGE_REF_QUERY } from "studio/lib/queries/navigation"; type CustomCallToActionsProps = ArrayOfObjectsInputProps< { _key: string }, @@ -28,7 +28,7 @@ const CustomCallToActions: React.FC = (props) => { const fetchLandingId = async () => { try { setLoading(true); - const landingId = await fetchWithToken(LANDING_QUERY); + const landingId = await fetchWithToken(LANDING_PAGE_REF_QUERY); setLandingPageId(landingId); } catch (error) { console.error("Failed to fetch navigation manager", error); diff --git a/studio/lib/interfaces/global.ts b/studio/lib/interfaces/global.ts index 1be127644..11aed98eb 100644 --- a/studio/lib/interfaces/global.ts +++ b/studio/lib/interfaces/global.ts @@ -7,3 +7,8 @@ export interface Reference { _type: "reference"; _ref: string; } + +export interface DocumentWithSlug { + slug: Slug; + _updatedAt: string; +} diff --git a/studio/lib/queries/document.ts b/studio/lib/queries/document.ts new file mode 100644 index 000000000..4e3f88efd --- /dev/null +++ b/studio/lib/queries/document.ts @@ -0,0 +1,5 @@ +import { groq } from "next-sanity"; + +export const DOCUMENTS_WITH_SLUG_QUERY = groq` + *[defined(slug)] +`; diff --git a/studio/lib/queries/navigation.ts b/studio/lib/queries/navigation.ts index 922e3d161..81d7c1d04 100644 --- a/studio/lib/queries/navigation.ts +++ b/studio/lib/queries/navigation.ts @@ -38,6 +38,10 @@ export const NAV_QUERY = groq` } `; -export const LANDING_QUERY = groq` +export const LANDING_PAGE_REF_QUERY = groq` *[_type == "navigationManager"][0].setLanding._ref `; + +export const LANDING_PAGE_QUERY = groq` + *[_type == "navigationManager"][0].setLanding -> +`;