Skip to content

Commit

Permalink
[wip] Feature: TanStackのルート定義からOGP分岐付きのindex.htmlを生成
Browse files Browse the repository at this point in the history
  • Loading branch information
ThinaticSystem committed Jul 2, 2024
1 parent a7bd0f5 commit 959417a
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 0 deletions.
71 changes: 71 additions & 0 deletions frontend/scripts/generate-template-html.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// @ts-check

import fs from "node:fs";
import process from "node:process";

import { routeTree } from "../src/routeTree.gen";

/** @typedef {import("../src/staticDataRouteOption").CustomStaticDataRouteOption} CustomStaticDataRouteOption */

/** 書き出すHTMLファイルのパス */
const distFile = process.cwd() + "/dist/index.html";

/** TanStack RouterのRouteの型の扱い方がよくわかんにゃいのでとりあえず */
/**
* @typedef {{
* children?: Record<string, RouteTree>;
* fullPath: string;
* options: {
* staticData: CustomStaticDataRouteOption;
* }
* }} RouteTree;
*/

/**
* Generate flatten routes array. Nested children will be pettanko. (Nippongo ga utenai in VS code, naniyue?)
* @param {RouteTree} parent
*/
const getFlattenRoutes = (parent) => {
/** @type {RouteTree[]} */
const flattenRoutes = [];
flattenRoutes.push(parent);
if (parent.children != null) {
// 子孫ルートを収集
for (const child of Object.values(parent.children)) {
flattenRoutes.push(...getFlattenRoutes(child));
}
}
return flattenRoutes;
};

const flattenRoutes = getFlattenRoutes(/** @type {RouteTree} */ (routeTree));
const html = `<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/png" href="/logo192.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- % switch (path) {
${(() =>
flattenRoutes.map(
(route) => ` case ${route.fullPath}: % -->
<meta property="og:title" content="${route.options.staticData.ogp.title}" />
<meta property="og:description" content="${route.options.staticData.ogp.description}" />
<meta property="og:url" content="<%- host + '${route.fullPath}' %>" />${
route.options.staticData.ogp.imageUrl != null
? `
<meta property="og:image" content="<%- host + '${route.options.staticData.ogp.imageUrl}' %>" />`
: ""
}`,
))()}>
<!-- %- ogpTag % -->
<title>Frost</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>`;

// htmlファイルへ書き込み
fs.writeFileSync(distFile, html);
6 changes: 6 additions & 0 deletions frontend/src/routes/__root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,10 @@ export const Route = createRootRoute({
<TanStackRouterDevtools />
</>
),
staticData: {
ogp: {
title: "",
description: "",
},
},
});
6 changes: 6 additions & 0 deletions frontend/src/routes/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ import { DeleteParrot } from "./-components/DeleteParrot";

export const Route = createFileRoute("/")({
component: Home,
staticData: {
ogp: {
title: "Frost",
description: "Top",
},
},
});

function Home() {
Expand Down
11 changes: 11 additions & 0 deletions frontend/src/staticDataRouteOption.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export interface CustomStaticDataRouteOption {
ogp: {
title: string;
description: string;
imageUrl?: string;
};
}

declare module "@tanstack/react-router" {
interface StaticDataRouteOption extends CustomStaticDataRouteOption {}
}

0 comments on commit 959417a

Please sign in to comment.