Getting started
Wire the Playwright matchers and write a first SEO spec
1. Install
npm install @sargonpiraev/seokit @playwright/test2. Extend expect
Create src/test/seokit.ts:
import { expect as baseExpect, test } from "@playwright/test";
import { extendSeokitExpect } from "@sargonpiraev/seokit";
const expect = extendSeokitExpect(baseExpect);
export { test, expect };Import test / expect from this file in SEO specs — not from @playwright/test directly.
3. Playwright project
import { defineConfig } from "@playwright/test";
export default defineConfig({
testDir: "./src",
testMatch: "**/*.seokit.spec.ts",
use: {
baseURL: process.env.PLAYWRIGHT_BASE_URL ?? "http://localhost:3000",
},
});npx playwright test4. First spec
Colocate next to the page, e.g. src/app/[locale]/page.seokit.spec.ts.
Recommended pattern: known locales × known URLs, with expectations in a test-only fixture file (not imported by the app):
import { test, expect } from "@/test/seokit";
const LOCALES = ["en", "de", "fr"] as const;
for (const locale of LOCALES) {
test(`/${locale}`, async ({ page }) => {
const response = await page.goto(`/${locale}`);
expect(response?.ok()).toBeTruthy();
await expect(page).toHaveMetadata({
lang: locale,
title: /.+/,
description: /.+/,
alternates: {
canonical: `https://example.com/${locale}`,
languages: {
en: "https://example.com/en",
de: "https://example.com/de",
fr: "https://example.com/fr",
"x-default": "https://example.com/en",
},
},
});
await expect(page).toHaveJsonLd([{ "@type": "Organization" }]);
});
}See the example app (src/test/seo-fixtures.ts + colocated *.seokit.spec.ts).
Full matcher reference: Matchers.
Optional: Next route helpers
@sargonpiraev/seokit/next also exports createSeokitPageRoutes / assertSeokitRouteBasics for next-intl route matrices driven by the Next build manifest. They need a prior next build. The example app uses the simpler fixture loops above; helpers are covered by package unit tests under packages/seokit/src/next/.