diff --git a/bun.lockb b/bun.lockb index e978070..6656860 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index dae2a35..093f7c3 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "remark-gfm": "^4.0.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.1", + "sitemap": "^8.0.0", "unified": "^11.0.5", "zustand": "^5.0.2" }, diff --git a/src/pages/posts/sitemap.xml.ts b/src/pages/posts/sitemap.xml.ts new file mode 100644 index 0000000..63a2677 --- /dev/null +++ b/src/pages/posts/sitemap.xml.ts @@ -0,0 +1,49 @@ +import { sni } from '@/services/network' +import { SnPost } from '@/services/post' +import { GetServerSideProps } from 'next' +import { EnumChangefreq, SitemapItem, SitemapStream, streamToPromise } from 'sitemap' +import { Readable } from 'stream' + +function generateSiteMap(posts: SnPost[]): Promise { + const links: SitemapItem[] = posts.map((p) => ({ + url: p.alias && p.aliasPrefix ? `/posts/${p.aliasPrefix}/${p.alias}` : `/posts/${p.id}`, + lastmod: (p.editedAt ?? p.publishedAt ?? p.editedAt)?.toString(), + changefreq: EnumChangefreq.DAILY, + priority: 0.9, + img: [], + video: [], + links: [], + })) + + const stream = new SitemapStream({ hostname: 'https://solsynth.dev' }) + + return streamToPromise(Readable.from(links).pipe(stream)).then((data) => data.toString()) +} + +export const getServerSideProps: GetServerSideProps = async ({ res, query }) => { + let page: number = parseInt(query.page as string) + if (isNaN(page)) page = 1 + + const countPerPage = 500 + + const { data: resp } = await sni.get<{ data: SnPost[] }>('/cgi/co/posts/minimal', { + params: { + take: countPerPage, + offset: (page - 1) * countPerPage, + }, + }) + + const sitemap = await generateSiteMap(resp.data) + + res.setHeader('Content-Type', 'text/xml') + res.write(sitemap) + res.end() + + return { + props: {}, + } +} + +export default function PostSiteMap() { + // getServerSideProps will do the heavy lifting +} diff --git a/src/pages/sitemap.xml.ts b/src/pages/sitemap.xml.ts new file mode 100644 index 0000000..2d9e161 --- /dev/null +++ b/src/pages/sitemap.xml.ts @@ -0,0 +1,64 @@ +import { GetServerSideProps } from 'next' +import { EnumChangefreq, SitemapItem, SitemapStream, streamToPromise } from 'sitemap' +import { Readable } from 'stream' + +function generateSiteMap(): Promise { + const links: SitemapItem[] = [ + { + url: '/', + lastmod: new Date().toString(), + changefreq: EnumChangefreq.WEEKLY, + priority: 0.7, + img: [], + video: [], + links: [], + }, + { + url: '/products/solar-network', + lastmod: new Date().toString(), + changefreq: EnumChangefreq.WEEKLY, + priority: 0.7, + img: [], + video: [], + links: [], + }, + { + url: '/posts', + lastmod: new Date().toString(), + changefreq: EnumChangefreq.HOURLY, + priority: 0.8, + img: [], + video: [], + links: [], + }, + { + url: '/posts/sitemap.xml', + lastmod: new Date().toString(), + changefreq: EnumChangefreq.HOURLY, + priority: 0.8, + img: [], + video: [], + links: [], + }, + ] + + const stream = new SitemapStream({ hostname: 'https://solsynth.dev' }) + + return streamToPromise(Readable.from(links).pipe(stream)).then((data) => data.toString()) +} + +export const getServerSideProps: GetServerSideProps = async ({ res, query }) => { + const sitemap = await generateSiteMap() + + res.setHeader('Content-Type', 'text/xml') + res.write(sitemap) + res.end() + + return { + props: {}, + } +} + +export default function PostSiteMap() { + // getServerSideProps will do the heavy lifting +}