🔍 Add sitemap
This commit is contained in:
		| @@ -34,6 +34,7 @@ | |||||||
|     "remark-gfm": "^4.0.0", |     "remark-gfm": "^4.0.0", | ||||||
|     "remark-parse": "^11.0.0", |     "remark-parse": "^11.0.0", | ||||||
|     "remark-rehype": "^11.1.1", |     "remark-rehype": "^11.1.1", | ||||||
|  |     "sitemap": "^8.0.0", | ||||||
|     "unified": "^11.0.5", |     "unified": "^11.0.5", | ||||||
|     "zustand": "^5.0.2" |     "zustand": "^5.0.2" | ||||||
|   }, |   }, | ||||||
|   | |||||||
							
								
								
									
										49
									
								
								src/pages/posts/sitemap.xml.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/pages/posts/sitemap.xml.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -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<string> { | ||||||
|  |   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 | ||||||
|  | } | ||||||
							
								
								
									
										64
									
								
								src/pages/sitemap.xml.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								src/pages/sitemap.xml.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | |||||||
|  | import { GetServerSideProps } from 'next' | ||||||
|  | import { EnumChangefreq, SitemapItem, SitemapStream, streamToPromise } from 'sitemap' | ||||||
|  | import { Readable } from 'stream' | ||||||
|  |  | ||||||
|  | function generateSiteMap(): Promise<string> { | ||||||
|  |   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 | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user