Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@ import partytown from '@astrojs/partytown'
import remarkMath from 'remark-math'
import rehypeKatex from 'rehype-katex'
import mdx from '@astrojs/mdx'
import { SITE } from './src/config.mjs'
import { getSitemapOptions } from './src/sitemap.mjs'

export default defineConfig({
site: 'https://4byte.dev',
site: SITE.origin,
output: 'static',
integrations: [
UnoCSS(),
mdx(),
icon(),
sitemap(),
sitemap(getSitemapOptions()),
partytown({
config: {
forward: ['dataLayer.push'],
Expand Down
94 changes: 94 additions & 0 deletions src/sitemap.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { readFileSync, readdirSync } from 'fs'
import { fileURLToPath } from 'url'
import { dirname, join } from 'path'
import { SITE, LANGUAGES, DEFAULT_LANG, SUPPORTED_LANGS } from './config.mjs'

const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)

function getArticleDates() {
const dates = {}
for (const lang of SUPPORTED_LANGS) {
const dir = join(__dirname, 'content/articles', lang)
try {
const files = readdirSync(dir).filter((f) => f.endsWith('.mdx'))
for (const file of files) {
const content = readFileSync(join(dir, file), 'utf-8')
const match = content.match(/^---\n([\s\S]*?)\n---/)
if (match) {
const frontmatter = match[1]
const slugMatch = frontmatter.match(/slug:\s*['"](.+?)['"]/)
const dateMatch = frontmatter.match(/date:\s*['"](.+?)['"]/)
if (slugMatch && dateMatch) {
dates[slugMatch[1]] = dateMatch[1]
}
}
}
} catch {
// directory doesn't exist or is empty
}
}
return dates
}

function getCustomPages() {
const pages = []
for (const lang of SUPPORTED_LANGS) {
const prefix = LANGUAGES[lang].prefix
try {
const categories = JSON.parse(readFileSync(join(__dirname, `data/${lang}/categories.json`), 'utf-8'))
for (const c of categories) {
pages.push(`${SITE.origin}${prefix}/categories/${c.slug}/`)
}
} catch {
// file doesn't exist or is empty
}
try {
const tags = JSON.parse(readFileSync(join(__dirname, `data/${lang}/tags.json`), 'utf-8'))
for (const t of tags) {
pages.push(`${SITE.origin}${prefix}/tags/${t.slug}/`)
}
} catch {
// file doesn't exist or is empty
}
}
return pages
}

const articleDates = getArticleDates()
const customPages = getCustomPages()

const i18n = {
defaultLocale: DEFAULT_LANG,
locales: Object.fromEntries(SUPPORTED_LANGS.map((lang) => [lang, LANGUAGES[lang].ogLocale.replace('_', '-')])),
}

export function getSitemapOptions() {
return {
filter: (page) => !page.includes('/404'),
i18n,
customPages,
serialize: (item) => {
const articleMatch = item.url.match(/\/articles\/([^/]+)\//)
if (articleMatch) {
const slug = articleMatch[1]
if (articleDates[slug]) {
item.lastmod = articleDates[slug]
}
item.changefreq = 'weekly'
item.priority = 0.8
return item
}

if (/\/(categories|tags)\/[^/]+\/$/.test(item.url)) {
item.changefreq = 'monthly'
item.priority = 0.6
return item
}

item.changefreq = 'weekly'
item.priority = 0.5
return item
},
}
}
Loading