diff options
| author | Yasutake Yohei <61961825+yasutakeyohei@users.noreply.github.com> | 2026-10-02 23:51:34 +0900 |
|---|---|---|
| committer | Yasutake Yohei <61961825+yasutakeyohei@users.noreply.github.com> | 2026-10-02 23:51:34 +0900 |
| commit | e332019acb312ec64893c26cf3d797d5ce472f26 (patch) | |
| tree | d97eaca75ad6d1d41658854d6b80519f6cd1ab79 /astro.config.mjs | |
| parent | 99204ebe327657ed4aaaa92d7f2d6e0cb04a6b3b (diff) | |
bluebey: ぶるべー スタジオのページを公開
Diffstat (limited to 'astro.config.mjs')
| -rw-r--r-- | astro.config.mjs | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/astro.config.mjs b/astro.config.mjs index 6b37a1a..bc9c803 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -1,3 +1,6 @@ +import { existsSync } from "node:fs"; +import { join } from "node:path"; +import { fileURLToPath } from "node:url"; import { defineConfig } from "astro/config"; import starlight from "@astrojs/starlight"; import sitemap from "@astrojs/sitemap"; @@ -5,6 +8,42 @@ import remarkMermaid from "remark-mermaidjs"; import ogImagePlugin from "./src/plugins/og-image"; import updatesIntegration from "./src/plugins/updates"; +// Apache (production) resolves a directory URL to its index.html, so the site can +// link to `/bluebey-studio/`. Vite's dev server serves `/bluebey-studio/index.html` +// but 404s on the directory form, so the link appears broken in `astro dev`. +// This serve-only middleware rewrites such a URL to the index file it points at, +// leaving the production output untouched. +function publicDirIndexPlugin() { + const publicDir = fileURLToPath(new URL("./public/", import.meta.url)); + return { + name: "serve-public-dir-index", + apply: "serve", + configureServer(server) { + server.middlewares.use((req, res, next) => { + const [pathname, query] = (req.url ?? "").split("?", 2); + // The studio is plain static files whose names never change, so a cached + // copy hides edits during development (the browser keeps running the old + // JS after it has been rebuilt). + if (pathname.startsWith("/bluebey-studio/")) { + res.setHeader("Cache-Control", "no-store"); + } + // Only directory requests (trailing slash) can need an index file. + if (!pathname.endsWith("/")) return next(); + let indexFile; + try { + indexFile = join(publicDir, decodeURIComponent(pathname), "index.html"); + } catch { + return next(); // malformed percent-encoding + } + // Make sure the path stayed inside public/ and the file really exists. + if (!indexFile.startsWith(publicDir) || !existsSync(indexFile)) return next(); + req.url = `${pathname}index.html${query ? `?${query}` : ""}`; + next(); + }); + }, + }; +} + export default defineConfig({ site: "https://yasutakeyohei.com", base: "/", @@ -12,6 +51,9 @@ export default defineConfig({ markdown: { remarkPlugins: [remarkMermaid], }, + vite: { + plugins: [publicDirIndexPlugin()], + }, integrations: [ sitemap(), updatesIntegration(), @@ -256,6 +298,18 @@ export default defineConfig({ }, ], }, + // The mascot studio is its own section on purpose: it is a personal + // hobby project, not one of the site's political-activity tools, and + // the ぶるべー character belongs to the city (see the page's opening note). + { + label: "つくってあそぶ", + items: [ + { + label: "ぶるべー スタジオ", + link: "/bluebey/", + }, + ], + }, { label: "ご支援", link: "/support/" }, { label: "コンタクト", link: "/contact/" }, { label: "私の方針", link: "/policy/" }, |
