Files
web/app/api/sitemap/route.ts
Erik Tiekstra c93381ca80 Merged in feat/SW-550-sitemap (pull request #981)
feat(SW-550): added sync functionality and sitemap generation

* feat(SW-550): added sync functionality and sitemap generation

* feat(SW-550): Added support for splitting and saving multiple sitemaps when there are 50000+ urls

* feat(SW-550): Updates after PR

* feat(SW-550): Added locale to sitemap data

* feat(SW-550): Added support for locale based sitemapData

* feat(SW-550): Saving alternates of sitemap entries

* feat(SW-550): Refactoring to use sitemap utils file

* feat(SW-550): Using Netlify.env to get environment variables

* feat(SW-550): clarify use of functions


Approved-by: Michael Zetterberg
2025-02-17 10:35:11 +00:00

100 lines
2.7 KiB
TypeScript

import dayjs from "dayjs"
import { type NextRequest, NextResponse } from "next/server"
import { env } from "@/env/server"
import {
getEntries,
getSyncToken,
saveEntries,
saveLastUpdatedDate,
saveSitemapData,
saveSyncToken,
} from "@/utils/sitemap"
import { contentstackSync } from "./sync"
import {
generateSitemapCounter,
generateSitemapFailCounter,
generateSitemapSuccessCounter,
saveEntriesCounter,
saveSitemapDataCounter,
saveSyncTokenCounter,
} from "./telemetry"
import { mapEntriesToSitemapData, mergeEntries } from "./utils"
export const dynamic = "force-dynamic"
export async function GET(request: NextRequest) {
try {
generateSitemapCounter.add(1)
console.info("sitemap.generate start")
const headersList = request.headers
const secret = headersList.get("x-sitemap-sync-secret")
if (secret !== env.SITEMAP_SYNC_SECRET) {
throw Error(
`Can't sync and generate sitemap, invalid secret, received secret: ${secret}`
)
}
const syncToken = await getSyncToken()
const currentEntries = await getEntries()
const responseData = await contentstackSync(syncToken)
const mergedEntries = mergeEntries(currentEntries, responseData.entries)
saveEntriesCounter.add(1, { entriesCount: mergedEntries.length })
console.info(
"sitemap.entries.save",
JSON.stringify({ entriesCount: mergedEntries.length })
)
await saveEntries(mergedEntries)
const sitemapData = mapEntriesToSitemapData(mergedEntries)
const lastUpdated = dayjs.utc().format()
saveSitemapDataCounter.add(1, {
sitemapEntriesCount: sitemapData.length,
})
console.info(
"sitemap.data.save",
JSON.stringify({
sitemapEntriesCount: sitemapData.length,
lastUpdated,
})
)
await saveSitemapData(sitemapData)
await saveLastUpdatedDate(lastUpdated)
if (syncToken !== responseData.syncToken) {
saveSyncTokenCounter.add(1, {
syncToken: responseData.syncToken,
})
console.info(
"sitemap.synctoken.save",
JSON.stringify({ syncToken: responseData.syncToken })
)
await saveSyncToken(responseData.syncToken)
}
generateSitemapSuccessCounter.add(1)
return NextResponse.json({
message: "Sitemap data generated and stored successfully!",
now: dayjs.utc().format(),
})
} catch (error) {
const errorMessage =
error instanceof Error ? error.message : JSON.stringify(error)
generateSitemapFailCounter.add(1, { error: errorMessage })
console.error("sitemap.generate.fail", errorMessage)
return NextResponse.json(
{
error: "Failed to generate sitemap",
now: dayjs.utc().format(),
},
{ status: 500, statusText: "Internal Server Error" }
)
}
}