<aside> 💡 ນອກຈາກເລື່ອງ Code ແລ້ວກໍ່ຍັງມີ File ຊະນິດພິເສດ ທີ່ຊ່ວຍໃຫ້ SEO ເຮັດວຽກໄດ້ດີຂຶ້ນອີກ.

</aside>

Robot: ເປັນຟາຍທີ່ຄວບຄຸມ ແລະ ກຳນົດຂອບເຂດສິດຂອງ robot crawler ເຮັດວຽກແນວໃດແນ່

Sitemap: ຊ່ວຍໃຫ້ bot ຮູ້ວ່າເຮົາຈະເອົາ ໜ້າໃດແນ່ໄປສະແດງເປັນຜົນລັບ

Robot.txt

// Nextjs Framework 
import type { MetadataRoute } from 'next'
 
export default function robots(): MetadataRoute.Robots {
  return {
    rules: {
      userAgent: '*',
      allow: '/',
      disallow: '/private/',
    },
    sitemap: '<https://acme.com/sitemap.xml>',
  }
}
// Output or Normal File
User-Agent: *
Allow: /
Disallow: /private/

Sitemap: <https://acme.com/sitemap.xml>

Sitemap.xml

// Nextjs Framework 
import type { MetadataRoute } from 'next'
 
export default function sitemap(): MetadataRoute.Sitemap {
  return [
    {
      url: '<https://acme.com>',
      lastModified: new Date(),
      changeFrequency: 'yearly',
      priority: 1,
    },
    {
      url: '<https://acme.com/about>',
      lastModified: new Date(),
      changeFrequency: 'monthly',
      priority: 0.8,
    },
    {
      url: '<https://acme.com/blog>',
      lastModified: new Date(),
      changeFrequency: 'weekly',
      priority: 0.5,
    },
  ]
}
// Output or Normal File
<urlset xmlns="<http://www.sitemaps.org/schemas/sitemap/0.9>">
  <url>
    <loc><https://acme.com></loc>
    <lastmod>2023-04-06T15:02:24.021Z</lastmod>
    <changefreq>yearly</changefreq>
    <priority>1</priority>
  </url>
  <url>
    <loc><https://acme.com/about></loc>
    <lastmod>2023-04-06T15:02:24.021Z</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.8</priority>
  </url>
  <url>
    <loc><https://acme.com/blog></loc>
    <lastmod>2023-04-06T15:02:24.021Z</lastmod>
    <changefreq>weekly</changefreq>
    <priority>0.5</priority>
  </url>
</urlset>

Dynamic Sitemap + Multi Lang (Real World Use Case)

const defaultLocale = "la";
const locales = ["la", "th", "en"];

export default async function sitemap() {
	const baseUrl = "<https://www.yourdomain.com>";

	const response = await fetch(
		`${process.env.API_LINK}/v1/api/product/sale?limit=1000`,
	);

	const productsData = await response.json();

	if (!productsData || !productsData.data || !productsData.data.data) {
		throw new Error("Invalid products data");
	}

	const productSitemap = productsData.data.data
		.map((product) => {
			const id = product?._id;
			if (!id) return null;

			const url = `${baseUrl}/product/${id}`;
			const lastModified = new Date().toISOString();

			return { url, lastModified };
		})
		.filter(Boolean);

	const staticPaths = ["/"]; // Add more static paths if needed

	const pathnames = [
		...staticPaths.map((path) => ({
			url: `${baseUrl}${path}`,
			lastModified: new Date().toISOString(),
		})),
		...productSitemap,
	];

	function getUrl(pathname, locale) {
		return `${baseUrl}/${locale}${pathname === baseUrl ? "" : pathname.replace(baseUrl, "")}`;
	}

	return pathnames.map((pathnameObj) => ({
		url: getUrl(pathnameObj.url, defaultLocale),
		lastModified: pathnameObj.lastModified,
		// alternates: {
		// 	languages: Object.fromEntries(
		// 		locales.map((locale) => [locale, getUrl(pathnameObj.url, locale)]),
		// 	),
		// },
	}));
}

Dynamic Robot + Multi Lang (Real World Use Case)

const locales = ["la", "th", "en"];

export default function robots() {
	const baseUrl = "<https://www.yourdomain.com>";

	const localizedPaths = locales.map((locale) => ({
		allow: ["/", `/${locale}/product`],
	}));

	const rules = {
		userAgent: "*",
		allow: [
			"/",
			...locales.flatMap((locale) => [`/${locale}`, `/${locale}/product`]),
		],
		disallow: [],
	};

	const sitemaps = locales.map((locale) => `${baseUrl}/${locale}/sitemap.xml`);

	return {
		rules,
		sitemap: sitemaps,
	};
}