From 8b5da6762c61cc65afbcd2db06f0986882048345 Mon Sep 17 00:00:00 2001 From: Jakub Zych Date: Wed, 4 Nov 2026 13:59:38 +0100 Subject: [PATCH] feat!: extend the SEO layer and drop the copied purge route - extend vue-seo-layer (link dependency during development); every page takes its head from the SEO plugin through it - remove the copied shared purge route, library, plugin and their test: POST /api/__site__/cache/purge comes from vue-seo-layer with the same contract and environment variables - the page-less playground sets seo.htmlSitemap false; the smoke points NUXT_SEO_API_BASE at the fixture API (fails open) BREAKING CHANGE: server/api/__site__/cache/purge.post.ts, server/lib/siteCachePurge.ts and server/plugins/site-cache-purge.ts are no longer in this layer, and the runtime keys cachePurge and siteCache are declared by vue-seo-layer. An app without pages sets seo.htmlSitemap false. --- .playground/nuxt.config.ts | 4 + README.md | 31 +- nuxt.config.ts | 40 +-- package.json | 3 + pnpm-lock.yaml | 195 ++++++----- server/api/__site__/cache/purge.post.ts | 48 --- server/lib/siteCachePurge.ts | 208 ----------- server/plugins/site-cache-purge.ts | 48 --- testing/smoke-ssr.mjs | 8 +- tests/sitePurge.test.ts | 438 ------------------------ 10 files changed, 132 insertions(+), 891 deletions(-) delete mode 100644 server/api/__site__/cache/purge.post.ts delete mode 100644 server/lib/siteCachePurge.ts delete mode 100644 server/plugins/site-cache-purge.ts delete mode 100644 tests/sitePurge.test.ts diff --git a/.playground/nuxt.config.ts b/.playground/nuxt.config.ts index cb4d490..257f89d 100644 --- a/.playground/nuxt.config.ts +++ b/.playground/nuxt.config.ts @@ -3,4 +3,8 @@ export default defineNuxtConfig({ extends: ['..'], compatibilityDate: '2025-07-15', + // An app without pages: vue-seo-layer's HTML sitemap pages would be its + // only routes and turn the router on, so every other path would answer + // 404. A site with pages keeps them. + seo: { htmlSitemap: false }, }) diff --git a/README.md b/README.md index eec8175..5ddd27a 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,8 @@ pnpm add git+https://git.golem15.com/golem15/vue-menu-layer.git#v0.2.0 The layer is consumed with `extends: ['vue-menu-layer']`. It reads one route of the menu plugin's anonymous API, `GET /_menu/api/v1/menus/{code}`, during SSR, so the first paint already has the menu, and renders it with ``. Editors manage menus in the SummerCMS admin; the site needs no menu data of its own. +The layer extends [vue-seo-layer](https://git.golem15.com/golem15/vue-seo-layer), which sets every page's head from the SummerCMS SEO plugin and serves the shared site cache purge route; an app that extends vue-menu-layer gets it with no extra entry in `extends`. + The layer is neutral: it ships no site colours, no site copy and no Nuxt modules. Its look comes from `--menu-*` CSS custom properties, which an app overrides, and every component can be replaced by a file of the same name in the app. ## Features @@ -20,7 +22,7 @@ The layer is neutral: it ships no site colours, no site copy and no Nuxt modules - **Active state**: the entry whose URL path equals the current route path (decoded, query, hash and trailing slash ignored; an absolute URL only on the request host) gets `aria-current="page"` and `menu-nav__link--active`; its ancestors get `menu-nav__item--trail`. - **Dividers**: `aria-hidden` list items, a horizontal line in panels and a short vertical line at the top level on the desktop. - **Empty states**: a missing menu (404), a failed request or a menu without entries renders nothing, or the `#fallback` slot. There is never an empty `