diff --git a/astro.config.ts b/astro.config.ts index d8e41f8b4..d0a52eb8f 100644 --- a/astro.config.ts +++ b/astro.config.ts @@ -102,6 +102,10 @@ export default defineConfig({ ], ], }, - output: "hybrid", - adapter: vercel(), + output: "server", + adapter: vercel({ + isr: { + expiration: 180, + }, + }), }); diff --git a/src/pages/api/index.astro b/src/pages/api/index.astro index 295eb6c4f..efcd8bc82 100644 --- a/src/pages/api/index.astro +++ b/src/pages/api/index.astro @@ -1,5 +1,8 @@ --- -import Redir from "~/layouts/Redir.astro"; +return new Response(null, { + status: 301, + headers: { + Location: "/api/rest-v1", + }, +}); --- - - diff --git a/src/pages/api/rest-v1/[...slug].astro b/src/pages/api/rest-v1/[...slug].astro index cd685db7f..67e5f6b18 100644 --- a/src/pages/api/rest-v1/[...slug].astro +++ b/src/pages/api/rest-v1/[...slug].astro @@ -8,8 +8,6 @@ import schema from "~/schema/v1.openapi.json"; import Component from "./_Page"; -export const prerender = false; - const { v1auth } = await getApiSectionDescriptions(); const { slug } = Astro.params; diff --git a/src/pages/api/rest-v2-legacy/[...slug].astro b/src/pages/api/rest-v2-legacy/[...slug].astro index ac0eb43ce..f4dbd9642 100644 --- a/src/pages/api/rest-v2-legacy/[...slug].astro +++ b/src/pages/api/rest-v2-legacy/[...slug].astro @@ -12,20 +12,11 @@ import Trackers from "~/layouts/Trackers.astro"; import TrackingScript from "~/layouts/TrackingScript.astro"; import type { Lang } from "~/type"; -export async function getStaticPaths() { - const docEntries = await getCollection("docs"); - const legacyV2ApiEntries = docEntries.filter((entry) => - entry.slug.startsWith("ko/api-v2/"), - ); - return legacyV2ApiEntries.map((entry) => { - const [_ko, _apiv2, ...fragments] = entry.slug.split("/"); - const slug = fragments.join("/"); - return { params: { slug }, props: { entry, slug } }; - }); -} - const lang: Lang = "ko"; -const { entry, slug } = Astro.props; +const { slug } = Astro.props; +const docEntries = await getCollection("docs"); +const entry = docEntries.find((entry) => entry.slug === `ko/api-v2/${slug}`); +if (!entry) return new Response(null, { status: 404 }); const { title, description } = entry.data; const mdx = await entry.render(); const Content = mdx.Content; diff --git a/src/pages/api/rest-v2-legacy/index.astro b/src/pages/api/rest-v2-legacy/index.astro index e6116bd71..cbf0d44d7 100644 --- a/src/pages/api/rest-v2-legacy/index.astro +++ b/src/pages/api/rest-v2-legacy/index.astro @@ -1,5 +1,8 @@ --- -import Redir from "~/layouts/Redir.astro"; +return new Response(null, { + status: 301, + headers: { + Location: "/api/rest-v2-legacy/v2-api", + }, +}); --- - - diff --git a/src/pages/api/rest-v2/[...slug].astro b/src/pages/api/rest-v2/[...slug].astro index b364f4ce6..6f00953a6 100644 --- a/src/pages/api/rest-v2/[...slug].astro +++ b/src/pages/api/rest-v2/[...slug].astro @@ -6,8 +6,6 @@ import schema from "~/schema/v2.openapi.json"; import Component from "./_Page"; -export const prerender = false; - const { slug } = Astro.params; const [_api, _rest, section = ""] = Astro.url.pathname .split("/") diff --git a/src/pages/blog/posts/[...slug].astro b/src/pages/blog/posts/[...slug].astro index 1f84cdd83..bda8eb071 100644 --- a/src/pages/blog/posts/[...slug].astro +++ b/src/pages/blog/posts/[...slug].astro @@ -15,26 +15,16 @@ import authors from "~/content/blog/_authors.yaml"; import LayoutBase from "~/layouts/LayoutBase.astro"; // import NavigationMenu from "~/components/blog/NavigationMenu"; -export async function getStaticPaths() { - const blogEntries = await getCollection("blog"); - return blogEntries.map((entry) => { - return { - params: { slug: entry.slug }, - props: { entry, slug: entry.slug }, - }; - }); -} - -const entriesPromise = getCollection("blog").then((entries) => +const { slug } = Astro.params; +const entries = await getCollection("blog").then((entries) => entries.sort((a, b) => b.data.date.getTime() - a.data.date.getTime()), ); +const entry = entries.find((entry) => entry.slug === slug); +if (!entry) return new Response(null, { status: 404 }); -const { entry } = Astro.props; const { title, description, author: authorId } = entry.data; const { Content, headings } = await entry.render(); -const entries = await entriesPromise; - const author = authors[authorId]; --- diff --git a/src/pages/blog/posts/[...slug].png.ts b/src/pages/blog/posts/[...slug].png.ts index 92508cb10..4907b0c25 100644 --- a/src/pages/blog/posts/[...slug].png.ts +++ b/src/pages/blog/posts/[...slug].png.ts @@ -4,8 +4,6 @@ import { getEntryBySlug } from "astro:content"; import authors from "~/content/blog/_authors.yaml"; import { generate } from "~/misc/opengraph/image-generator"; -export const prerender = false; - export const GET: APIRoute = async ({ params }) => { const { slug } = params; const entry = await getEntryBySlug("blog", slug!); diff --git a/src/pages/blog/tags/[tag].astro b/src/pages/blog/tags/[tag].astro index 2c2fcb129..d14c372f1 100644 --- a/src/pages/blog/tags/[tag].astro +++ b/src/pages/blog/tags/[tag].astro @@ -1,22 +1,9 @@ --- -import type { GetStaticPaths } from "astro"; import { getCollection } from "astro:content"; import PostListLayout from "~/components/blog/PostList/PostListLayout.astro"; -export const getStaticPaths: GetStaticPaths = async () => { - const collection = await getCollection("blog"); - const tags = new Set(); - for (const entry of collection) { - for (const tag of entry.data.tags) { - tags.add(tag); - } - } - return Array.from(tags).map((tag) => ({ params: { tag } })); -}; - const tag = decodeURIComponent(Astro.params.tag?.toString() ?? ""); - const entries = await getCollection( "blog", (entry) => @@ -25,6 +12,7 @@ const entries = await getCollection( import.meta.env.DEV || import.meta.env.VERCEL_ENV === "preview"), ); +if (entries.length === 0) return new Response(null, { status: 404 }); --- diff --git a/src/pages/content-index/[fileName].json.ts b/src/pages/content-index/[fileName].json.ts index 34769cb78..a416689af 100644 --- a/src/pages/content-index/[fileName].json.ts +++ b/src/pages/content-index/[fileName].json.ts @@ -1,10 +1,8 @@ -import type { APIRoute, GetStaticPaths } from "astro"; +import type { APIRoute } from "astro"; import * as yaml from "js-yaml"; import { toPlainText } from "~/misc/mdx"; -export const prerender = true; - const indexFilesMapping = { blog: "blog/", "docs-en": "docs/en/", @@ -15,11 +13,6 @@ type IndexFileName = keyof typeof indexFilesMapping; const isIndexFileName = (value: string): value is IndexFileName => value in indexFilesMapping; -export const getStaticPaths: GetStaticPaths = () => - Object.keys(indexFilesMapping).map((fileName) => ({ - params: { fileName }, - })); - export const GET: APIRoute = async ({ params }) => { const { fileName } = params; const slug = diff --git a/src/pages/docs/[lang]/[...slug].astro b/src/pages/docs/[lang]/[...slug].astro index 9bfc56e9b..2fc42b7d4 100644 --- a/src/pages/docs/[lang]/[...slug].astro +++ b/src/pages/docs/[lang]/[...slug].astro @@ -1,62 +1,27 @@ --- -import * as path from "node:path"; - -import type { GetStaticPathsItem } from "astro"; -import type { CollectionEntry } from "astro:content"; import { getCollection } from "astro:content"; -import { match, P } from "ts-pattern"; import redirYaml from "~/content/docs/_redir.yaml"; import Docs from "~/layouts/Docs.astro"; -import Redir from "~/layouts/Redir.astro"; - -import type { Lang } from "../../../type"; +import { isLang } from "~/type"; -export async function getStaticPaths() { - const docEntries = await getCollection("docs"); - const staticPaths: Record = {}; - for (const entry of docEntries) { - const [lang, ...fragments] = entry.slug.split("/"); - const absSlug = path.posix.join("/", entry.slug); - const slug = fragments.join("/"); - staticPaths[entry.slug] = { - params: { lang, slug }, - props: { entry, slug: absSlug }, - }; - } - for (const redir of redirYaml) { - const entrySlug = redir.old.slice(1); - const [lang, ...fragments] = entrySlug.split("/"); - const slug = fragments.join("/"); - staticPaths[entrySlug] = { - params: { lang, slug }, - props: { redirTarget: redir.new }, - }; - } - return Object.values(staticPaths); +const { lang, slug } = Astro.params; +if (!isLang(lang) || !slug) { + return new Response(null, { status: 404 }); } -type Props = - | { redirTarget: string } - | { - entry: CollectionEntry<"docs">; - slug: string; - }; +const absSlug = `/${lang}/${slug}`; +const redir = redirYaml.find(({ old }) => old === absSlug); +if (redir) { + return new Response(null, { + status: 301, + headers: { Location: redir.new }, + }); +} -const lang = Astro.params.lang as Lang; +const entries = await getCollection("docs"); +const entry = entries.find((entry) => entry.slug === `${lang}/${slug}`); +if (!entry) return new Response(null, { status: 404 }); --- -{ - match(Astro.props) - .with({ redirTarget: P.string }, ({ redirTarget }) => - redirTarget.startsWith("https:") ? ( - - ) : ( - - ), - ) - .with({ slug: P.string, entry: P.any }, ({ slug, entry }) => ( - - )) - .exhaustive() -} + diff --git a/src/pages/docs/[lang]/[...slug].png.ts b/src/pages/docs/[lang]/[...slug].png.ts index 9eea99a2a..15539f32e 100644 --- a/src/pages/docs/[lang]/[...slug].png.ts +++ b/src/pages/docs/[lang]/[...slug].png.ts @@ -3,8 +3,6 @@ import { getEntryBySlug } from "astro:content"; import { generate } from "~/misc/opengraph/image-generator"; -export const prerender = false; - export const GET: APIRoute = async ({ params }) => { const { lang, slug } = params; const entry = await getEntryBySlug("docs", `${lang}/${slug}`); diff --git a/src/pages/docs/[lang]/index.astro b/src/pages/docs/[lang]/index.astro index ab4416cfe..38329095a 100644 --- a/src/pages/docs/[lang]/index.astro +++ b/src/pages/docs/[lang]/index.astro @@ -1,12 +1,10 @@ --- -import Redir from "~/layouts/Redir.astro"; +import { isLang } from "~/type"; -import type { Lang } from "../../../type"; - -export async function getStaticPaths() { - return ["ko", "en"].map((lang) => ({ params: { lang } })); -} -const lang = Astro.params.lang as Lang; +const { lang } = Astro.params; +if (!isLang(lang)) return new Response(null, { status: 404 }); +return new Response(null, { + status: 301, + headers: { Location: `/docs/${lang}/readme` }, +}); --- - - diff --git a/src/pages/docs/index.astro b/src/pages/docs/index.astro index 56bdd1f38..c36e98756 100644 --- a/src/pages/docs/index.astro +++ b/src/pages/docs/index.astro @@ -1,5 +1,8 @@ --- -import Redir from "~/layouts/Redir.astro"; +return new Response(null, { + status: 301, + headers: { + Location: "/docs/ko/readme", + }, +}); --- - - diff --git a/src/pages/opengraph.png.ts b/src/pages/opengraph.png.ts index b1b9b6534..bb380e30d 100644 --- a/src/pages/opengraph.png.ts +++ b/src/pages/opengraph.png.ts @@ -2,8 +2,6 @@ import type { APIRoute } from "astro"; import { generate } from "~/misc/opengraph/image-generator"; -export const prerender = false; - export const GET: APIRoute = async () => { const response = await generate({}); return new Response(response, { diff --git a/src/pages/platform/[...slug].astro b/src/pages/platform/[...slug].astro index 5f4af75bb..14d44e7f4 100644 --- a/src/pages/platform/[...slug].astro +++ b/src/pages/platform/[...slug].astro @@ -10,19 +10,10 @@ import RightSidebar, { headingsToToc } from "~/layouts/sidebar/RightSidebar"; import Trackers from "~/layouts/Trackers.astro"; import TrackingScript from "~/layouts/TrackingScript.astro"; -export async function getStaticPaths() { - const docEntries = await getCollection("docs"); - const platformEntries = docEntries.filter((entry) => - entry.slug.startsWith("ko/platform/"), - ); - return platformEntries.map((entry) => { - const [_ko, _platform, ...fragments] = entry.slug.split("/"); - const slug = fragments.join("/"); - return { params: { slug }, props: { entry, slug } }; - }); -} - -const { entry, slug } = Astro.props; +const { slug } = Astro.props; +const entries = await getCollection("docs"); +const entry = entries.find((entry) => entry.slug === `ko/platform/${slug}`); +if (!entry) return new Response(null, { status: 404 }); const { title, description } = entry.data; const mdx = await entry.render(); const Content = mdx.Content; diff --git a/src/pages/release-notes/[...slug].astro b/src/pages/release-notes/[...slug].astro index 9769cf3a3..e6a305302 100644 --- a/src/pages/release-notes/[...slug].astro +++ b/src/pages/release-notes/[...slug].astro @@ -1,5 +1,4 @@ --- -import type { InferGetStaticParamsType, InferGetStaticPropsType } from "astro"; import { format } from "date-fns"; import * as prose from "~/components/prose"; @@ -9,31 +8,20 @@ import LayoutBase from "~/layouts/LayoutBase.astro"; import Nav from "~/layouts/release-notes/Nav.astro"; import { getReleaseNotes } from "~/misc/releaseNote"; -export async function getStaticPaths() { - const { apiSdkNotes, consoleNotes } = await getReleaseNotes(); - return [ - ...apiSdkNotes.map(({ slug, entry }) => ({ - params: { slug }, - props: { entry, apiSdkNotes, consoleNotes }, - })), - ...consoleNotes.map(({ slug, entry }) => ({ - params: { slug }, - props: { entry, apiSdkNotes, consoleNotes }, - })), - ]; -} +const { slug } = Astro.params; +if (!slug) return new Response(null, { status: 404 }); +const { apiSdkNotes, consoleNotes } = await getReleaseNotes(); +const { entry } = + [...apiSdkNotes, ...consoleNotes].find((entry) => entry.slug === slug) ?? {}; +if (!entry) return new Response(null, { status: 404 }); -type Params = InferGetStaticParamsType; -type Props = InferGetStaticPropsType; - -const { slug } = Astro.params as Params; -const { entry, apiSdkNotes, consoleNotes } = Astro.props as Props; +const type = entry.slug.startsWith("api-sdk") ? "apiSdkNotes" : "consoleNotes"; const { releasedAt, writtenAt } = entry.data; const { Content } = await entry.render(); - -const label = apiSdkNotes.some((note) => note.slug === slug) - ? "API / SDK" - : "관리자콘솔"; +const label = { + apiSdkNotes: "API / SDK", + consoleNotes: "관리자콘솔", +}[type]; const title = `${format(releasedAt, "yyyy-MM-dd")} ${label} 업데이트`; --- diff --git a/src/type.ts b/src/type.ts index dc56f51e4..36b9733e2 100644 --- a/src/type.ts +++ b/src/type.ts @@ -1,5 +1,9 @@ export type Lang = "ko" | "en"; +export const isLang = (lang: unknown): lang is Lang => { + return ["ko", "en"].includes(String(lang)); +}; + export type SystemVersion = "all" | "v1" | "v2"; export type YamlNavMenuToplevelItem =