From 81275c03951ddb6fd059383c369f0b699c2d096d Mon Sep 17 00:00:00 2001 From: rasm-its Date: Mon, 28 Sep 2026 14:54:21 +0200 Subject: [PATCH] Added css asset for sitemap --- dist/modules/seo/asseets/sitemap.css | 76 +++++++++ docs/seo.md | 246 ++++++++++++++------------- src/modules/seo/asseets/sitemap.css | 76 +++++++++ 3 files changed, 277 insertions(+), 121 deletions(-) create mode 100644 dist/modules/seo/asseets/sitemap.css create mode 100644 src/modules/seo/asseets/sitemap.css diff --git a/dist/modules/seo/asseets/sitemap.css b/dist/modules/seo/asseets/sitemap.css new file mode 100644 index 0000000..d28b43a --- /dev/null +++ b/dist/modules/seo/asseets/sitemap.css @@ -0,0 +1,76 @@ +/* + * Starter stylesheet for a sitemap served via buildSitemapXml({ cssUrl }). + * Uses type="text/css" on XML (W3C "Associating Style Sheets with XML") — NOT + * XSLT, so no browser deprecation warning. Selectors are the XML tag names. + * + * Copy to your project's /public/sitemap.css and adjust colors/spacing to taste. + * Crawlers ignore this; it only affects the human-readable browser view. + */ + +urlset { + display: block; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + background: #090d16; + color: #f1f5f9; + padding: 2rem 1.5rem; + max-width: 1200px; + margin: 0 auto; + line-height: 1.5; +} + +/* Each URL entry as a card. */ +url { + display: block; + background: #111827; + border: 1px solid #1e293b; + border-radius: 8px; + padding: 1rem 1.25rem; + margin-bottom: 0.75rem; +} + +/* The URL itself. */ +loc { + display: block; + font-size: 0.95rem; + font-weight: 600; + color: #f97316; + margin-bottom: 0.5rem; + word-break: break-all; +} + +/* Metadata line: lastmod / changefreq / priority, each with a label. */ +lastmod, +changefreq, +priority { + display: inline-block; + font-size: 0.8rem; + color: #94a3b8; + margin-right: 1.5rem; +} + +lastmod::before { + content: 'Ostatnia modyfikacja: '; + color: #64748b; +} + +changefreq::before { + content: 'Częstotliwość: '; + color: #64748b; +} + +priority::before { + content: 'Priorytet: '; + color: #64748b; +} + +/* hreflang alternates as small pills. */ +link { + display: inline-block; + font-size: 0.75rem; + background: #1e293b; + color: #38bdf8; + border: 1px solid #334155; + padding: 0.15rem 0.45rem; + border-radius: 4px; + margin: 0.4rem 0.35rem 0 0; +} \ No newline at end of file diff --git a/docs/seo.md b/docs/seo.md index 83fdf2b..d183976 100644 --- a/docs/seo.md +++ b/docs/seo.md @@ -19,14 +19,14 @@ admina i bez importMap się nie wyrenderują. ```ts ipalKit({ - seo: { - collections: ['pages', 'posts'], // które kolekcje dostają meta - // generateTitle: ({ doc }) => `${doc.title}`, // opcjonalne - // generateDescription: ({ doc }) => doc.excerpt ?? '', - // fields: [...], // extra pola w grupie SEO - // autoFill: { title: 'title', description: 'excerpt' }, // mapowanie auto-fill - // autoFill: false, // wyłącz auto-fill - }, + seo: { + collections: ['pages', 'posts'], // które kolekcje dostają meta + // generateTitle: ({ doc }) => `${doc.title}`, // opcjonalne + // generateDescription: ({ doc }) => doc.excerpt ?? '', + // fields: [...], // extra pola w grupie SEO + // autoFill: { title: 'title', description: 'excerpt' }, // mapowanie auto-fill + // autoFill: false, // wyłącz auto-fill + }, }) ``` @@ -89,16 +89,16 @@ import { createPageMetadata } from '@intecion/ipal-kit' import { i18nConfig } from '@/i18n.config' const pageMetadata = createPageMetadata({ - config: i18nConfig, - baseUrl: process.env.NEXT_PUBLIC_SERVER_URL, - // collection: 'pages', // domyślne - // settingsSlug: 'site-settings', // domyślne - // siteNameField: 'siteName', // domyślne + config: i18nConfig, + baseUrl: process.env.NEXT_PUBLIC_SERVER_URL, + // collection: 'pages', // domyślne + // settingsSlug: 'site-settings', // domyślne + // siteNameField: 'siteName', // domyślne }) export async function generateMetadata({ params }): Promise { - const { locale, slug } = await params - return pageMetadata({ payload: await getPayload({ config }), locale, slug }) + const { locale, slug } = await params + return pageMetadata({ payload: await getPayload({ config }), locale, slug }) } ``` @@ -121,43 +121,43 @@ global. Klient dostarcza resolvery. import { createMetadataGenerator } from '@intecion/ipal-kit' const generate = createMetadataGenerator({ - config: i18nConfig, - baseUrl: process.env.NEXT_PUBLIC_SERVER_URL, - homeSlug: 'homepage', + config: i18nConfig, + baseUrl: process.env.NEXT_PUBLIC_SERVER_URL, + homeSlug: 'homepage', - resolveDocument: async ({ payload, params, locale }) => { - const slug = (params.slug as string[])?.join('/') + resolveDocument: async ({ payload, params, locale }) => { + const slug = (params.slug as string[])?.join('/') - // meta MUSI przyjść w konkretnym locale (stringi), a slug jako mapa - // locale→wartość (hreflang) — to dwa różne odczyty. - const found = await payload.find({ - collection: 'posts', - where: { slug: { equals: slug } }, - locale, - depth: 1, - limit: 1, - }) - const doc = found.docs[0] - if (!doc) return null + // meta MUSI przyjść w konkretnym locale (stringi), a slug jako mapa + // locale→wartość (hreflang) — to dwa różne odczyty. + const found = await payload.find({ + collection: 'posts', + where: { slug: { equals: slug } }, + locale, + depth: 1, + limit: 1, + }) + const doc = found.docs[0] + if (!doc) return null - const allLocales = await payload.findByID({ - collection: 'posts', - id: doc.id, - locale: 'all', - depth: 0, - }) + const allLocales = await payload.findByID({ + collection: 'posts', + id: doc.id, + locale: 'all', + depth: 0, + }) - return { ...doc, slug: allLocales.slug } - }, + return { ...doc, slug: allLocales.slug } + }, - resolveSiteName: async ({ payload, locale }) => - (await getSiteSettings(payload, { locale })).siteName ?? null, - resolveImageUrl: async ({ doc }) => doc.meta?.image?.url ?? null, + resolveSiteName: async ({ payload, locale }) => + (await getSiteSettings(payload, { locale })).siteName ?? null, + resolveImageUrl: async ({ doc }) => doc.meta?.image?.url ?? null, }) export async function generateMetadata({ params }) { - const { locale, slug } = await params - return generate({ payload: await getPayload({ config }), params: { slug }, locale }) + const { locale, slug } = await params + return generate({ payload: await getPayload({ config }), params: { slug }, locale }) } ``` @@ -176,16 +176,16 @@ Gdy chcesz pełną kontrolę: import { buildMetadata, getLocalizedSlugs } from '@intecion/ipal-kit' return buildMetadata({ - meta: doc.meta, // z plugin-seo - siteName: settings.siteName, - imageUrl: '/og.png', - locale: 'pl', - slugs: getLocalizedSlugs({ slugField: docAllLocales.slug, config }), - config, - baseUrl: 'https://example.com', - separator: ' – ', // opcjonalne - order: 'site-first', // opcjonalne - homeSlug: 'homepage', + meta: doc.meta, // z plugin-seo + siteName: settings.siteName, + imageUrl: '/og.png', + locale: 'pl', + slugs: getLocalizedSlugs({ slugField: docAllLocales.slug, config }), + config, + baseUrl: 'https://example.com', + separator: ' – ', // opcjonalne + order: 'site-first', // opcjonalne + homeSlug: 'homepage', }) // → { title, description, openGraph, alternates: { canonical, languages } } ``` @@ -232,10 +232,10 @@ nie rozjedzie się z tym, co strony serwują. Handlery są gotowe w ```ts // src/lib/content.ts export const { /* ... */, sitemap, robots } = createContentHelpers({ - config, - content: contentConfig, - i18n: i18nConfig, // wymagane dla sitemap (hreflang) - baseUrl: process.env.NEXT_PUBLIC_SERVER_URL, + config, + content: contentConfig, + i18n: i18nConfig, // wymagane dla sitemap (hreflang) + baseUrl: process.env.NEXT_PUBLIC_SERVER_URL, }) ``` @@ -278,7 +278,7 @@ Niskopoziomowo (własna trasa zamiast handlera z fabryki): import { buildSitemapEntries, buildRobots } from '@intecion/ipal-kit' const entries = await buildSitemapEntries({ - payload, config: i18nConfig, baseUrl, content: contentConfig, + payload, config: i18nConfig, baseUrl, content: contentConfig, }) ``` @@ -321,9 +321,9 @@ import { buildIconsMetadata } from '@intecion/ipal-kit' import { getSettings } from '@/lib/payload' export async function generateMetadata({ params }): Promise { - const { locale } = await params - const settings = await getSettings(locale) - return buildIconsMetadata(settings.favicon) // z pola favicon (panel) + const { locale } = await params + const settings = await getSettings(locale) + return buildIconsMetadata(settings.favicon) // z pola favicon (panel) } ``` @@ -346,16 +346,16 @@ wynikach, logo w knowledge panel. import { buildOrganizationJsonLd } from '@intecion/ipal-kit' const jsonLd = buildOrganizationJsonLd({ - name: settings.siteName, - url: process.env.NEXT_PUBLIC_SERVER_URL!, - logo: settings.logo, - sameAs: settings.socialLinks, // opcjonalne: profile społecznościowe - }) + name: settings.siteName, + url: process.env.NEXT_PUBLIC_SERVER_URL!, + logo: settings.logo, + sameAs: settings.socialLinks, // opcjonalne: profile społecznościowe +}) - // w JSX layoutu: -