-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathastro.config.mjs
More file actions
150 lines (146 loc) · 5.47 KB
/
Copy pathastro.config.mjs
File metadata and controls
150 lines (146 loc) · 5.47 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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// @ts-check
import { defineConfig } from 'astro/config';
import react from '@astrojs/react';
import sitemap, { ChangeFreqEnum } from '@astrojs/sitemap';
import tailwindcss from '@tailwindcss/vite';
import rehypeSlug from 'rehype-slug';
import rehypeAutolinkHeadings from 'rehype-autolink-headings';
import { lastModified, pageReleases, pageSources } from './src/lib/lastmod.ts';
import { getReleases } from './src/lib/github.ts';
/**
* Wraps every markdown table in a container that scrolls sideways. The page
* clips horizontal overflow (global.css), so a table wider than a phone screen
* would otherwise be cut off rather than scroll.
*/
function rehypeScrollingTables() {
/** @param {any} node */
const visit = (node) => {
if (!Array.isArray(node.children)) return;
node.children = node.children.map((/** @type {any} */ child) => {
if (child.type === 'element' && child.tagName === 'table') {
// Focusable, like the code blocks, so that it can be scrolled from the keyboard.
return { type: 'element', tagName: 'div', properties: { className: ['table-scroll'], tabIndex: 0 }, children: [child] };
}
visit(child);
return child;
});
};
return (/** @type {any} */ tree) => visit(tree);
}
// https://astro.build/config
export default defineConfig({
site: 'https://thinkwat.ch',
// Pages that moved. GitHub Pages cannot answer with a redirect, so each old
// address is built as a page that sends the browser on (and is not indexed).
redirects: {
'/license': '/pricing',
'/zh-CN/license': '/zh-CN/pricing',
},
i18n: {
defaultLocale: 'en',
locales: ['en', 'zh-CN'],
routing: {
prefixDefaultLocale: false,
},
},
integrations: [
react(),
sitemap({
i18n: {
defaultLocale: 'en',
locales: { en: 'en', 'zh-CN': 'zh-CN' },
},
// The import page only reads the parameters of a link; it has nothing to index.
filter: (page) => !page.includes('/404') && !/\/(zh-CN\/)?import\/?$/.test(new URL(page).pathname),
async serialize(item) {
const url = new URL(item.url);
const pathname = url.pathname.replace(/\/$/, '') || '/';
const isHome = pathname === '/' || pathname === '/zh-CN';
const isDoc = pathname.startsWith('/docs/') || pathname.startsWith('/zh-CN/docs/');
const isDocsIndex = pathname === '/docs' || pathname === '/zh-CN/docs';
const isChangelog = pathname === '/changelog' || pathname === '/zh-CN/changelog';
// Product landing pages: ThinkWatch, ThinkWatch Lite, ThinkWatch Core.
const productPaths = ['/thinkwatch', '/lite', '/core'];
const isProduct = productPaths.some((p) => pathname === p || pathname === `/zh-CN${p}`);
const isPricing = pathname === '/pricing' || pathname === '/zh-CN/pricing';
if (isHome) {
item.priority = 1.0;
item.changefreq = ChangeFreqEnum.WEEKLY;
} else if (isProduct) {
item.priority = 0.9;
item.changefreq = ChangeFreqEnum.WEEKLY;
} else if (isDocsIndex) {
item.priority = 0.9;
item.changefreq = ChangeFreqEnum.WEEKLY;
} else if (isDoc) {
// Includes the product doc sets under /docs/lite/ and /docs/core/.
item.priority = 0.8;
item.changefreq = ChangeFreqEnum.MONTHLY;
} else if (isChangelog) {
item.priority = 0.7;
item.changefreq = ChangeFreqEnum.WEEKLY;
} else if (isPricing) {
item.priority = 0.6;
item.changefreq = ChangeFreqEnum.MONTHLY;
} else {
item.priority = 0.5;
item.changefreq = ChangeFreqEnum.MONTHLY;
}
// When the page's own files last changed in git, or the latest release
// of a product the page shows came out, whichever is later. Left out
// without git history: a release date alone does not say when the
// page itself last changed.
const committed = lastModified(pageSources(pathname));
if (committed) {
let latest = Date.parse(committed);
const products = pageReleases(pathname);
if (products.length) {
// Newest first: the first match is the latest release among them.
const release = (await getReleases()).find((r) => products.includes(r.product));
if (release) latest = Math.max(latest, Date.parse(release.date));
}
item.lastmod = new Date(latest).toISOString();
}
return item;
},
}),
],
markdown: {
shikiConfig: {
theme: 'github-dark-default',
wrap: false,
},
rehypePlugins: [
rehypeScrollingTables,
rehypeSlug,
[
rehypeAutolinkHeadings,
{
behavior: 'append',
properties: {
className: ['heading-anchor'],
ariaLabel: 'Link to this section',
},
content: {
type: 'text',
value: '#',
},
},
],
],
},
vite: {
plugins: [tailwindcss()],
build: {
// Font files are always emitted as files (src/components/Fonts.astro).
// Vite would otherwise inline those under 4 KB, the smaller Unicode
// subsets of Geist, into the stylesheet as base64, and every page would
// download subsets it never uses before its first paint. Anything else
// keeps the default limit.
assetsInlineLimit: (file) => (/\.woff2?$/.test(file) ? false : undefined),
},
},
build: {
inlineStylesheets: 'auto',
},
});