-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathvite-plugin-sitemap.ts
More file actions
67 lines (61 loc) · 1.92 KB
/
Copy pathvite-plugin-sitemap.ts
File metadata and controls
67 lines (61 loc) · 1.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import type { Plugin } from 'vite';
import { readdirSync, readFileSync } from 'fs';
import { join } from 'path';
interface SitemapOpts {
siteUrl: string;
staticRoutes: string[];
blogDir: string;
}
export function sitemapPlugin(opts: SitemapOpts): Plugin {
function buildSitemap(): string {
const urls = [...opts.staticRoutes];
// Add blog post slugs
try {
const files = readdirSync(opts.blogDir).filter((f) => f.endsWith('.svx'));
for (const file of files) {
const content = readFileSync(join(opts.blogDir, file), 'utf-8');
const draftMatch = content.match(/^---\n[\s\S]*?\ndraft:\s*(true|false)[\s\S]*?\n---/);
if (draftMatch && draftMatch[1] === 'true') continue;
const slug = file.replace(/\.svx$/, '');
// News/press articles live under /news; everything else under /blog.
const tagsMatch = content.match(/tags:\s*\[([^\]]*)\]/);
const tags = tagsMatch ? tagsMatch[1].split(',').map((s) => s.trim()) : [];
const isNews = tags.some((t) => t === 'news' || t === 'press');
urls.push(isNews ? `/news/${slug}` : `/blog/${slug}`);
}
} catch {
// no blog dir yet
}
const entries = urls
.map(
(path) =>
` <url>\n <loc>${opts.siteUrl}${path}</loc>\n </url>`,
)
.join('\n');
return `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${entries}
</urlset>
`;
}
return {
name: 'sitemap',
configureServer(server) {
server.middlewares.use((req, res, next) => {
if (req.url === '/sitemap.xml') {
res.setHeader('Content-Type', 'application/xml; charset=utf-8');
res.end(buildSitemap());
return;
}
next();
});
},
generateBundle() {
this.emitFile({
type: 'asset',
fileName: 'sitemap.xml',
source: buildSitemap(),
});
},
};
}