From e4c362030d256a9c60ca906a69d9de3efbd95ec2 Mon Sep 17 00:00:00 2001
From: xy <10816187@qq.com>
Date: Fri, 14 Aug 2026 23:55:52 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E5=8A=A8=E6=80=81sitemap.xml?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
astro.config.mjs | 7 +----
package.json | 1 -
pnpm-lock.yaml | 53 ----------------------------------
public/robots.txt | 2 ++
src/consts.ts | 2 +-
src/pages/sitemap-pages.xml.ts | 33 +++++++++++++++++++++
src/pages/sitemap-posts.xml.ts | 35 ++++++++++++++++++++++
src/pages/sitemap.xml.ts | 21 ++++++++++++++
src/types/post.ts | 6 ++++
9 files changed, 99 insertions(+), 61 deletions(-)
create mode 100644 src/pages/sitemap-pages.xml.ts
create mode 100644 src/pages/sitemap-posts.xml.ts
create mode 100644 src/pages/sitemap.xml.ts
diff --git a/astro.config.mjs b/astro.config.mjs
index 7c5c985..477b767 100644
--- a/astro.config.mjs
+++ b/astro.config.mjs
@@ -2,7 +2,6 @@
import {defineConfig} from 'astro/config';
import solidJs from '@astrojs/solid-js';
import node from '@astrojs/node';
-import sitemap from "@astrojs/sitemap";
// https://astro.build/config
export default defineConfig({
@@ -11,11 +10,7 @@ export default defineConfig({
server: {
host: "0.0.0.0",
},
- integrations: [solidJs(), sitemap({
- filter: (page) => {
- return !page.includes('/embed/');
- }
- })],
+ integrations: [solidJs()],
adapter: node({
mode: 'standalone'
}),
diff --git a/package.json b/package.json
index a6e43c0..4e8dfef 100644
--- a/package.json
+++ b/package.json
@@ -11,7 +11,6 @@
},
"dependencies": {
"@astrojs/node": "11.0.2",
- "@astrojs/sitemap": "^3.7.3",
"@astrojs/solid-js": "^5.1.3",
"astro": "^7.0.6",
"dayjs": "^1.11.21",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 1d65d15..81afef9 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -11,9 +11,6 @@ importers:
'@astrojs/node':
specifier: 11.0.2
version: 11.0.2(astro@7.0.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.2)(@types/node@26.1.0)(rollup@4.62.2))
- '@astrojs/sitemap':
- specifier: ^3.7.3
- version: 3.7.3
'@astrojs/solid-js':
specifier: ^5.1.3
version: 5.1.3(@types/node@26.1.0)(lightningcss@1.32.0)(solid-js@1.9.14)
@@ -146,9 +143,6 @@ packages:
resolution: {integrity: sha512-KTivpmnz6lDsC6o9H4+DNm2SrE/GHzw8cNAvEJwAvUT+eoaEnn/4NtbDNfRRaxaJHdp15gf+tfHAWiXR4wB3BA==}
engines: {node: '>=22.12.0'}
- '@astrojs/sitemap@3.7.3':
- resolution: {integrity: sha512-f8euLVsyeAmAkSm/1M2Kb8sL8byQmfgbvBNaHFItCheTj/IpiJYSEWVcqDHZ/yEHxiS7+w87mQkzwZaPHmk5GA==}
-
'@astrojs/solid-js@5.1.3':
resolution: {integrity: sha512-KxfYt4y1d7BuSw6EsN1EaPoGYsIES7bEI6AtTbncuabRUUMZs+mOWOeOdmgnwVLj+jbNbhBjUZsqr77eUviZdw==}
engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0}
@@ -1177,15 +1171,9 @@ packages:
'@types/nlcst@2.0.3':
resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==}
- '@types/node@24.13.2':
- resolution: {integrity: sha512-fRa09kZTgu8o71KFcDjUFuc7F+dEbZYZmkI0mg5YBTRs0yMKjYHsq/c0urDKeDb+D5qVgXOdFcuu+DZPKOITwA==}
-
'@types/node@26.1.0':
resolution: {integrity: sha512-O0A1G3xPGy4w7AgQdAQYUlQ+BKk2Oovw8eRpofyp5KdBZULnbe+WqaOVNrm705SHphCiG4XHsACrSmPu1f+Kgw==}
- '@types/sax@1.2.7':
- resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==}
-
'@types/tough-cookie@4.0.5':
resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==}
@@ -1203,9 +1191,6 @@ packages:
resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
engines: {node: '>= 8'}
- arg@5.0.2:
- resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
-
argparse@2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
@@ -1937,11 +1922,6 @@ packages:
sisteransi@1.0.5:
resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
- sitemap@9.0.1:
- resolution: {integrity: sha512-S6hzjGJSG3d6if0YoF5kTyeRJvia6FSTBroE5fQ0bu1QNxyJqhhinfUsXi9fH3MgtXODWvwo2BDyQSnhPQ88uQ==}
- engines: {node: '>=20.19.5', npm: '>=10.8.2'}
- hasBin: true
-
smol-toml@1.7.0:
resolution: {integrity: sha512-aqVvWoyO21L23mb+drl4RmMXbf6N7FdHjAhTRA9ZBL7apWBgfWC16KjrASI+1p9GAroljyMHj6fK67i0UiTNvQ==}
engines: {node: '>= 18'}
@@ -1965,9 +1945,6 @@ packages:
resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==}
engines: {node: '>= 0.8'}
- stream-replace-string@2.0.0:
- resolution: {integrity: sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==}
-
stringify-entities@4.0.4:
resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==}
@@ -2031,9 +2008,6 @@ packages:
uncrypto@0.1.3:
resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==}
- undici-types@7.18.2:
- resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==}
-
undici-types@7.28.0:
resolution: {integrity: sha512-LJAfY+2w6HGeT8d8J1wNQsUGUEGio6NWWpwdwurQe4f6oojzCFuGLizl1KSve4irsTxyLly1QhEeE6iapdaIvQ==}
@@ -2394,12 +2368,6 @@ snapshots:
dependencies:
prismjs: 1.30.0
- '@astrojs/sitemap@3.7.3':
- dependencies:
- sitemap: 9.0.1
- stream-replace-string: 2.0.0
- zod: 4.4.3
-
'@astrojs/solid-js@5.1.3(@types/node@26.1.0)(lightningcss@1.32.0)(solid-js@1.9.14)':
dependencies:
solid-js: 1.9.14
@@ -3162,18 +3130,10 @@ snapshots:
dependencies:
'@types/unist': 3.0.3
- '@types/node@24.13.2':
- dependencies:
- undici-types: 7.18.2
-
'@types/node@26.1.0':
dependencies:
undici-types: 8.3.0
- '@types/sax@1.2.7':
- dependencies:
- '@types/node': 26.1.0
-
'@types/tough-cookie@4.0.5': {}
'@types/unist@3.0.3': {}
@@ -3189,8 +3149,6 @@ snapshots:
normalize-path: 3.0.0
picomatch: 2.3.2
- arg@5.0.2: {}
-
argparse@2.0.1: {}
aria-query@5.3.2: {}
@@ -4050,13 +4008,6 @@ snapshots:
sisteransi@1.0.5: {}
- sitemap@9.0.1:
- dependencies:
- '@types/node': 24.13.2
- '@types/sax': 1.2.7
- arg: 5.0.2
- sax: 1.6.0
-
smol-toml@1.7.0: {}
solid-js@1.9.14:
@@ -4080,8 +4031,6 @@ snapshots:
statuses@2.0.2: {}
- stream-replace-string@2.0.0: {}
-
stringify-entities@4.0.4:
dependencies:
character-entities-html4: 2.1.0
@@ -4139,8 +4088,6 @@ snapshots:
uncrypto@0.1.3: {}
- undici-types@7.18.2: {}
-
undici-types@7.28.0: {}
undici-types@8.3.0: {}
diff --git a/public/robots.txt b/public/robots.txt
index c2a49f4..7a9e93e 100644
--- a/public/robots.txt
+++ b/public/robots.txt
@@ -1,2 +1,4 @@
User-agent: *
Allow: /
+
+Sitemap: https://ua42.com/sitemap-index.xml
diff --git a/src/consts.ts b/src/consts.ts
index 00ac662..ab3587a 100644
--- a/src/consts.ts
+++ b/src/consts.ts
@@ -1,5 +1,5 @@
export const metadata = {
+ site: "https://ua42.com",
siteTitle: "Uroboros",
-
postPageSize: 6
}
diff --git a/src/pages/sitemap-pages.xml.ts b/src/pages/sitemap-pages.xml.ts
new file mode 100644
index 0000000..aa035b4
--- /dev/null
+++ b/src/pages/sitemap-pages.xml.ts
@@ -0,0 +1,33 @@
+import type {APIRoute} from 'astro';
+import {metadata} from "@/consts";
+
+const site = metadata.site
+
+const staticUrls = [
+ '',
+ '/archives',
+ '/search',
+];
+
+export const GET: APIRoute = async () => {
+ const urls = staticUrls
+ .filter((url, index, array) => {
+ return array.indexOf(url) === index;
+ });
+
+ const xml = `
+ ${urls.map((url) => `
+ ${site}${url}
+ `
+ )
+ .join('\n')}
+`;
+
+ return new Response(xml, {
+ status: 200,
+ headers: {
+ 'Content-Type': 'application/xml; charset=utf-8',
+ 'Cache-Control': 'public, max-age=3600, s-maxage=3600',
+ },
+ });
+};
diff --git a/src/pages/sitemap-posts.xml.ts b/src/pages/sitemap-posts.xml.ts
new file mode 100644
index 0000000..b5ff3d1
--- /dev/null
+++ b/src/pages/sitemap-posts.xml.ts
@@ -0,0 +1,35 @@
+import type {APIRoute} from 'astro';
+import {metadata} from "@/consts";
+import {createHttp} from "@/lib/request.ts";
+import type {PostForSitemap} from "@/types";
+import dayjs from "dayjs";
+
+const site = metadata.site
+
+export const GET: APIRoute = async (context) => {
+ const http = createHttp(context.request.headers);
+
+ const {data} = await http.get>("posts/sitemap")
+
+ const urls = data
+ .filter((url, index, array) => {
+ return array.indexOf(url) === index;
+ });
+
+ const xml = `
+ ${urls.map((post) => `
+ ${site}/${post.slug}
+ ${dayjs(post.updated_at || post.created_at).toISOString()}
+ `
+ )
+ .join('\n')}
+`;
+
+ return new Response(xml, {
+ status: 200,
+ headers: {
+ 'Content-Type': 'application/xml; charset=utf-8',
+ 'Cache-Control': 'public, max-age=3600, s-maxage=3600',
+ },
+ });
+};
diff --git a/src/pages/sitemap.xml.ts b/src/pages/sitemap.xml.ts
new file mode 100644
index 0000000..46d1ece
--- /dev/null
+++ b/src/pages/sitemap.xml.ts
@@ -0,0 +1,21 @@
+import type {APIRoute} from 'astro';
+import {metadata} from "@/consts";
+
+const site = metadata.site
+
+export const GET: APIRoute = () => {
+ const xml = `
+
+ ${site}/sitemap-pages.xml
+
+
+ ${site}/sitemap-posts.xml
+
+`;
+
+ return new Response(xml, {
+ headers: {
+ 'Content-Type': 'application/xml; charset=utf-8',
+ },
+ });
+};
diff --git a/src/types/post.ts b/src/types/post.ts
index ac9e139..621081f 100644
--- a/src/types/post.ts
+++ b/src/types/post.ts
@@ -24,3 +24,9 @@ export type CategoriesStats = {
code: string
post_count: number;
}
+
+export type PostForSitemap = {
+ slug: string
+ created_at: string
+ updated_at: string
+}