Sivukartan luominen dynaamisesti

julkaistu 20.11.2024

Sivukartan (sitemap) luomiseen on useita tapoja, ja oikea valinta riippuu sivuston rakenteesta. Jos sivustolla ei ole dynaamisesti tuotettuja sivuja, riittää yleensä, että luo sitemap.xml-tiedoston projektin juureen ja päivittää sitä tarvittaessa, kun sivuston rakenne muuttuu. Dynaamisia sivuja sisältävillä sivustoilla, kuten verkkokaupan tuotesivut tai blogijulkaisut, sivukartta tulee rakentaa dynaamisesti.

Sivukartan rakenne

Sivukartan tulee sisältää <urlset>, <url> ja <loc>-tagit, ja kaikkien URL-osoitteiden tulee viitata samaan pääosoitteeseen, kuten esimerkiksi example.com.

<?xml version="1.0" encoding="UTF-8"?>

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    <url>
        <loc>https://example.com</loc>
        <lastmod>2022-01-12</lastmod>
    </url>
    <url>
        <loc>https://example.com/about</loc>
        <lastmod>2022-01-12</lastmod>
    </url>
</urlset>
  • lastmod-tagi kertoo, milloin sivun sisältö on viimeksi päivitetty. Käytä formaattia YYYY-MM-DD.
  • changefreq-tagi kertoo hakukoneille, kuinka usein sivun sisältö muuttuu. Hakukoneet eivät kuitenkaan välttämättä noudata tätä ohjeistusta.
  • priority-tagi määrittää sivun tärkeyden asteikolla 0–1. Tämä ei vaikuta sivun näkyvyyteen suhteessa muihin sivustoihin.

Dynaamisen sivukartan luominen

Tehdään esimerkki dynaamisesta sivukartasta SvelteKit-frameworkissa. Sama prosessi onnistuu muissakin frameworkeissa pienin koodimuutoksin.

Uuden projektin alustaminen

luodaan uusi SvelteKit projekti komennoilla:

npm create svelte@latest my-app
cd my-app
npm install
npm run dev

Nyt uusi projekti näkyy selaimen osoitteessa localhost:5173. Seuraavaksi luodaan rajapinta projektin tiedostoon src/routes/api/posts/+server.ts ja kopioidaan esimerkissä oleva data sinne.

Esimerkissä rajapinta palauttaa esimerkkisivujen tiedot:

import { json, type RequestHandler } from "@sveltejs/kit";

// src/routes/api/posts/+server.ts
export const GET: RequestHandler = async () => {
  // tiedot haettaisiin normaalisti tietokannasta tässä
  const posts = [
    {
      title: "Huuhkaja",
      slug: "huuhkaja",
      description: "Huuhkaja (Bubo bubo) on suurikokoinen pöllölaji...",
      updated: "2024-09-19 07:54:14.837Z",
    },
    {
      title: "Varis",
      slug: "varis",
      description: "Varis (Corvus corone) on ihmisasutuksen lähellä viihtyvä lintu...",
      updated: "2024-09-19 07:54:14.837Z",
    },
    {
      title: "Korppi",
      slug: "korppi",
      description: "Korppi eli kaarne (Corvus corax) on suurikokoinen musta varisten heimoon kuuluva lintu...",
      updated: "2024-09-19 07:54:14.837Z",
    },
  ];

  return json(posts);
};

Sivukartan luominen

Luodaan uusi sitemap.xml-kansio routes-hakemistoon ja sinne +server.ts-tiedosto. Tiedostossa haetaan julkaisut aiemmin luodusta rajapinnasta ja luodaan dynaamisesti sivukartan sisältö:

import { dev } from "$app/environment";

export async function GET() {
  const headers = {
    "Cache-Control": `max-age=0, s-max-age=604800`, // tallenetaan vastaus välimuistiin
    "Content-Type": "application/xml", // vastauksen tyyppi
  };

  // Kehitystilassa käytetään localhostia, muuten sivun urlia
  const website = dev ? "http://localhost:5173" : "https://www.example.com";

  // Sivut, joita ei generoida dynaamisesti
  const pages = ["linnut"];

  // Rajapinnan tietotyyppi
  type PostType = {
    title: string;
    slug: string;
    description: string;
    updated: string;
  };

  // haetaan julkaisut rajapinnasta
  const res = await fetch(`${website}/api/posts`);
  const posts: Array<PostType> = await res.json();

  // tehdään sivukartta rajapinnan datasta
  return new Response(
    `
<?xml version="1.0" encoding="UTF-8" ?>
<urlset xmlns="https://www.sitemaps.org/schemas/sitemap/0.9">
        <url>
            <loc>${website}</loc>
        </url>
    ${pages
      .map(
        (page) => `
        <url>
            <loc>${website}/${page}</loc>
        </url>`
      )
      .join("")}
    ${posts
      .map(
        ({ slug, updated }) => `
        <url>
            <loc>${website}/linnut/${slug}</loc>
            <lastmod>${updated}</lastmod>
        </url>`
      )
      .join("")}
</urlset>`.trim(),
    { headers }
  );
}

nyt sivukartan pitäisi näkyä selaimessa osoitteessa http://localhost:5173/sitemap.xml

<urlset xmlns="https://www.sitemaps.org/schemas/sitemap/0.9">
	<url>
		<loc>http://localhost:5173</loc>
	</url>
	<url>
		<loc>http://localhost:5173/linnut</loc>
	</url>
	<url>
		<loc>http://localhost:5173/linnut/huuhkaja</loc>
		<lastmod>2024-09-19 07:54:14.837Z</lastmod>
	</url>
	<url>
		<loc>http://localhost:5173/linnut/varis</loc>
		<lastmod>2024-09-19 07:54:14.837Z</lastmod>
	</url>
	<url>
		<loc>http://localhost:5173/linnut/korppi</loc>
		<lastmod>2024-09-19 07:54:14.837Z</lastmod>
	</url>
</urlset>

Kun rajapinnan data muuttuu, sivukartta päivittyy dynaamisesti vastaamaan uutta dataa.