Commit Graph

6 Commits

Author SHA1 Message Date
Jakub Zych
f2d13d6264 feat: pagination component and composable
- <SeoPagination> (UI-SPEC L2): previous and next (left out at the
  ends), page 1, the last page and five pages around the current one with
  gap items; nothing when last <= 1; props current, last, labels,
  classPrefix, locale
- usePagination(): hrefs in the CMS form (resolve answer, then site
  answer, then seo.pagination), other query parameters kept, page 1
  unnumbered, <link rel=prev/next> in the head
- the CMS head fills %pages% in the title and description once the
  listing's page count is known (seoFillPages)
- seoPaginationWindow, seoPageHref, seoPageNumber; L2 default styles
2026-11-04 11:59:51 +01:00
Jakub Zych
ebb0c8084e feat: breadcrumbs component
- <SeoBreadcrumbs> (UI-SPEC L1): the resolve answer's trail as nav > ol
  with server-rendered links and the last item as aria-current text;
  nothing with fewer than two items, with page meta seo.breadcrumbs false
  or with the option seo.breadcrumbs false; props items, label,
  hideCurrent, locale
- one trail per page: the first rendered instance claims it
  (seoClaimBreadcrumbs, kept per path)
- seoSitePath: same-origin CMS URLs become paths, non-http(s) URLs are
  never links; useSeoLabels takes an optional locale
- L1 default styles with CSS-generated separators
2026-11-04 11:59:17 +01:00
Jakub Zych
3abc986f42 feat: route report and drift check at server start
- the module writes #seo-routes (static paths and route patterns) from the
  resolved pages; options seo.routeReport, seo.pagination and
  seo.htmlSitemap reach the public runtime config
- seo-route-report: POST /registry/routes once per process with the
  route-report token, one retry after 60 s on failure, nothing without a
  token, with the layer off or with routeReport false
- seo-drift: one "[vue-seo-layer] drift:" warning per mismatch between
  the CMS's site answer (URL patterns, pagination, HTML sitemap paths)
  and the build
- GET /api/__seo__/site and useSeoSite()
- smoke grammar routereport and log, fixture registry route, drift run
2026-11-04 11:49:21 +01:00
Jakub Zych
aa7480e003 feat: SEO labels, tokens and base styles
- useSeoLabels(): the L8 dictionary (en, pl) of the page's content locale
  (resolve locale, then html_lang, then en), overridable and extendable in
  app.config.ts under seo.labels; no i18n dependency
- seo-tokens.css (spacing, colour, small type, breadcrumb separator) and
  seo-base.css (.seo-visually-hidden, the focus ring of layer links), loaded
  before the app's CSS and styling only .seo-* classes
2026-11-04 09:27:57 +01:00
Jakub Zych
160b53b2f5 feat: CMS head and one JSON-LD graph on every server-rendered page (tracer)
- Nitro middleware resolves page requests once and hands the answer to the
  render (event.context.seo); the route middleware reuses it
- useCmsSeo: html lang, hreflang links, og:locale and exactly one JSON-LD
  script with one @graph (CMS nodes plus useSchemaNode nodes, merged by @id)
- local module (configKey seo): cms (alias of public.seo.enabled),
  breadcrumbs, links.newTabHint, rootFiles, resolveFiles
- GET /api/__seo__/resolve for client navigation through the Nuxt server
- smoke harness: count=, exact header=, noheader=, reqheader=, repeated
  options, resolves/apicalls/noreport lines, --no-site; v0.1.1 suite runs
  unchanged against a backend without /site
2026-11-04 09:15:26 +01:00
Jakub Zych
ac59f3c80d feat: vue-seo-layer, the Nuxt half of the SummerCMS SEO plugin 2026-10-31 13:45:37 +01:00