// site/scripts/prerender.mjs // `vite build`(브라우저용)와 `vite build --ssr`(서버용) 뒤에 실행한다. // 언어마다 본문이 채워진 HTML(dist/index.html, dist//index.html)과 // sitemap.xml, robots.txt, llms.txt, llms-full.txt 를 만든다. // 크롤러(검색·AI)는 JavaScript 를 실행하지 않아도 전체 내용을 읽을 수 있다. import { mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs' import { dirname, join } from 'node:path' import { fileURLToPath, pathToFileURL } from 'node:url' const siteRoot = join(dirname(fileURLToPath(import.meta.url)), '..') const dist = join(siteRoot, 'dist') const ssrDir = join(siteRoot, 'dist-ssr') const server = await import(pathToFileURL(join(ssrDir, 'entry-server.js')).href) const template = readFileSync(join(dist, 'index.html'), 'utf8') for (const marker of ['', '', '']) { if (!template.includes(marker)) throw new Error(`prerender: index.html 에 ${marker} 가 없다`) } for (const { code } of server.LOCALES) { const html = template .replace('', ``) .replace('', server.buildHead(code)) .replace('', server.render(code)) const out = join(dist, server.localePath(code), 'index.html') mkdirSync(dirname(out), { recursive: true }) writeFileSync(out, html) } const lastmod = new Date().toISOString().slice(0, 10) writeFileSync(join(dist, 'sitemap.xml'), server.buildSitemap(lastmod)) writeFileSync(join(dist, 'robots.txt'), server.buildRobots()) writeFileSync(join(dist, 'llms.txt'), server.buildLlms()) writeFileSync(join(dist, 'llms-full.txt'), server.buildLlmsFull()) writeFileSync(join(dist, 'indexnow-urls.json'), JSON.stringify(server.sitemapUrls(), null, 2)) rmSync(ssrDir, { recursive: true, force: true }) console.log(`[prerender] ${server.LOCALES.length} locales + sitemap.xml, robots.txt, llms.txt, llms-full.txt`)