diff --git a/apps/blog/astro.config.js b/apps/blog/astro.config.js index 12e5cd4c..bea7d14c 100644 --- a/apps/blog/astro.config.js +++ b/apps/blog/astro.config.js @@ -28,4 +28,4 @@ export default defineConfig({ markdown: { remarkPlugins: [remarkPlugin], }, -}); +}); \ No newline at end of file diff --git a/apps/blog/package.json b/apps/blog/package.json index 3de1745b..70044878 100644 --- a/apps/blog/package.json +++ b/apps/blog/package.json @@ -5,6 +5,7 @@ "dependencies": { "@astrojs/react": "^4.1.2", "@astrojs/rss": "^4.0.11", + "@astrojs/sitemap": "^3.2.1", "@astrojs/tailwind": "^5.1.4", "@astrojs/vercel": "^8.0.1", "@crocoder-dev/remark-plugin": "*", diff --git a/apps/blog/public/robots.txt b/apps/blog/public/robots.txt new file mode 100644 index 00000000..282b669d --- /dev/null +++ b/apps/blog/public/robots.txt @@ -0,0 +1,4 @@ +User-agent: * +Allow: / + +Sitemap: https://crocoder.dev/blog/sitemap.xml \ No newline at end of file diff --git a/apps/blog/src/layouts/head.astro b/apps/blog/src/layouts/head.astro index 256334b3..67371f30 100644 --- a/apps/blog/src/layouts/head.astro +++ b/apps/blog/src/layouts/head.astro @@ -50,7 +50,7 @@ const allPartialsPlainText = ( const sufix = import.meta.env.DEV ? "" : "blog/"; -const siteUrl = import.meta.env.SITE_URL + sufix; +const siteUrl = import.meta.env.PUBLIC_SITE_URL + sufix; const posts = await getCollection("posts"); const currentPost = posts.find((post) => post.slug === slug); diff --git a/apps/blog/src/pages/sitemap.xml.ts b/apps/blog/src/pages/sitemap.xml.ts new file mode 100644 index 00000000..3feb51ed --- /dev/null +++ b/apps/blog/src/pages/sitemap.xml.ts @@ -0,0 +1,47 @@ +import { getCollection } from "astro:content"; +const markdownPosts = await getCollection("posts"); + +const prefix = import.meta.env.DEV ? "/" : "/blog"; +const siteUrl = import.meta.env.PUBLIC_SITE_URL + (prefix === "/" ? "" : prefix); + +export function GET() { + const posts = [ + ...markdownPosts.map((post: any) => ({ + url: `${siteUrl}/${post.slug}`, + createdAt: post.data.createdAt + ? new Date(post.data.createdAt) + : new Date(), + imageUrl: `${siteUrl}${post.data.image}`, + })), + ]; + + posts.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime()); + + const urls = posts + .map( + (post) => ` + + ${post.url} + ${post.createdAt} + ${ + post.imageUrl + ? ` + + ${post.imageUrl} + ` + : "" + } + 1 + + `, + ) + .join(""); + + return new Response( + ` + + ${urls} + `, + { headers: { "Content-Type": "application/xml" } }, + ); +} diff --git a/apps/website/astro.config.mjs b/apps/website/astro.config.mjs index dbf17081..5dd5a4e8 100644 --- a/apps/website/astro.config.mjs +++ b/apps/website/astro.config.mjs @@ -3,7 +3,11 @@ import tailwind from "@astrojs/tailwind"; import react from "@astrojs/react"; import vercel from "@astrojs/vercel/static"; +// https://astro.build/config export default defineConfig({ + // redirects: { + // '/sitemap': '/sitemap.xml', + // }, output: "static", adapter: vercel({ imageService: true, diff --git a/apps/website/public/robots.txt b/apps/website/public/robots.txt new file mode 100644 index 00000000..e2c5f974 --- /dev/null +++ b/apps/website/public/robots.txt @@ -0,0 +1,4 @@ +User-agent: * +Allow: / + +Sitemap: https://crocoder.dev/sitemap.xml \ No newline at end of file diff --git a/apps/website/src/components/navigation.astro b/apps/website/src/components/navigation.astro index 5633e881..f74c5960 100644 --- a/apps/website/src/components/navigation.astro +++ b/apps/website/src/components/navigation.astro @@ -85,14 +85,14 @@ data-navhidden class="flex flex-col md:flex-row gap-7 mx-7 md:mx-0 md:ml-20 md:w-auto relative top-1" > -
  • +
  • + + ${siteUrl} + ${new Date()} + 1 + `, + ]; + if (blogUrl) { + try { + const blogSitemapRes = await fetch(`${blogUrl}/sitemap.xml`); + if (blogSitemapRes.ok) { + const blogSitemap = await blogSitemapRes.text(); + const blogUrls = blogSitemap.match(/[\s\S]*?<\/url>/g) || []; + urls.push(...blogUrls); + } + } catch (error) { + console.error('Error fetching blog sitemap:', error); + } + } + + return new Response( + ` + + ${urls.join("")} + `, + { headers: { "Content-Type": "application/xml" } }, + ); +}