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 =