From 23156d09d3f53e822618f54b97bba4b3c77c85df Mon Sep 17 00:00:00 2001 From: Gil Hanan Date: Fri, 3 Nov 2023 23:11:16 +0200 Subject: [PATCH] SEO --- public/robots.txt | 4 +++ src/app/sitemap.test.ts | 60 +++++++++++++++++++++++++++++++++++++++++ src/app/sitemap.ts | 30 +++++++++++++++++++++ 3 files changed, 94 insertions(+) create mode 100644 public/robots.txt create mode 100644 src/app/sitemap.test.ts create mode 100644 src/app/sitemap.ts diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..fd25021 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,4 @@ +User-agent: * +Allow: / + +Sitemap: https://gil-hanan.com/sitemap.xml \ No newline at end of file diff --git a/src/app/sitemap.test.ts b/src/app/sitemap.test.ts new file mode 100644 index 0000000..c351cc8 --- /dev/null +++ b/src/app/sitemap.test.ts @@ -0,0 +1,60 @@ +import { MetadataRoute } from "next"; +import { projects } from "@data/projects"; +import sitemap from "@app/sitemap"; + +jest.mock("./data/projects", () => ({ + projects: [{ id: "project1" }, { id: "project2" }], +})); + +describe("sitemap", () => { + const host = "https://gil-hanan.com"; + let lastModified: Date; + let sitemapResult: MetadataRoute.Sitemap; + + beforeEach(() => { + lastModified = new Date(); + jest.useFakeTimers().setSystemTime(lastModified); + sitemapResult = sitemap(); + }); + + afterEach(() => { + jest.useRealTimers(); + }); + + it("should include the required static URLs", () => { + const staticUrls = [ + host, + `${host}/projects`, + `${host}/about`, + `${host}/contact`, + ]; + + staticUrls.forEach((url) => { + expect(sitemapResult).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + url, + }), + ]), + ); + }); + }); + + it("should include all projects with correct URLs", () => { + projects.forEach(({ id }) => { + expect(sitemapResult).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + url: `${host}/projects/${id}`, + }), + ]), + ); + }); + }); + + it("should have lastModified date set for all entries", () => { + sitemapResult.forEach((entry) => { + expect(entry.lastModified).toEqual(lastModified); + }); + }); +}); diff --git a/src/app/sitemap.ts b/src/app/sitemap.ts new file mode 100644 index 0000000..6813383 --- /dev/null +++ b/src/app/sitemap.ts @@ -0,0 +1,30 @@ +import { MetadataRoute } from "next"; +import { projects } from "@data/projects"; + +export default function sitemap(): MetadataRoute.Sitemap { + const host = "https://gil-hanan.com"; + const lastModified = new Date(); + + return [ + { + url: host, + lastModified, + }, + { + url: `${host}/projects`, + lastModified, + }, + { + url: `${host}/about`, + lastModified, + }, + { + url: `${host}/contact`, + lastModified, + }, + ...projects.map(({ id }) => ({ + url: `${host}/projects/${id}`, + lastModified, + })), + ]; +}