# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.5.4] - 2026-06-16

### Added

- Added route-policy-aware CMS site runtime support for preview, revalidation, sitemap, and resource route generation.

### Changed

- Updated the `@vigilkids/cms-client` peer dependency to `^0.3.3`.

## [0.5.1] - 2026-06-05

### Fixed

- Ordered CMS redirect middleware rules by priority, match specificity, and source path length.
- Updated the `@vigilkids/cms-client` peer dependency to `^0.3.1` for redirect priority metadata.

## [0.5.0] - 2026-06-03

### Added

- Added `useLocalizedResourceSeo()` for locale-aware CMS resource metadata, canonical links, Open Graph tags, and Twitter Card tags.
- Added category metadata exposure in `useCmsCategories()` for taxonomy landing pages.

### Changed

- `useBlogSeo()` now delegates to the shared localized resource SEO pipeline.
- Updated peer dependency to `@vigilkids/cms-client ^0.3.0`.

## [0.4.0] - 2026-06-03

### Added

- Product-agnostic Resource Route Policy through `routes.resources`, `routes.sourceResources`, and `routes.locale`, allowing each consuming product to define public CMS resource paths without changing package runtime code.
- Configurable CMS content integration endpoints: article collection path, CMS fetch proxy path, preview path, revalidate path, and sitemap source path.
- `useCmsRoutes()` composable for route-policy access and resource path generation.
- `useCmsArticleCollection()` composable backed by the module-owned normalized article collection endpoint.
- `useCmsCategories()` composable for preloaded category data, category lookup, and route-policy category path generation.
- Generic preview route resolution for resource types and route params, including source route parsing and route-policy public redirects.
- Route-policy-aware sitemap source endpoint and optional `@nuxtjs/sitemap` provider integration.

### Changed

- Module setup now uses the `cms` module options as the source of truth and derives server/private and public runtime config from those options.
- Preview, revalidate, and sitemap URL generation now build paths from Resource Route Policy instead of a fixed article URL shape.
- Client-side CMS fetches now use the module CMS proxy while SSR fetches continue to call the CMS API directly.
- Dynamic CMS endpoints are registered with no-cache Nitro route rules.

### Removed

- Package-owned hardcoded public article route assumptions from preview, revalidate, and sitemap path generation.
- Direct consumer setup guidance that required writing CMS runtime config keys manually.

## [0.3.0] - 2026-05-08

### Breaking Changes

- `useArticle` no longer auto-injects hreflang `<link>` tags. The previous implementation hardcoded a `/blog/{slug}` URL pattern, which silently produced incorrect `href` values for any consumer whose article routes are not exactly `/{locale}/blog/{slug}` (e.g. category-based routes like `/{locale}/{category}/{slug}/`). Hreflang URL pattern is consumer-domain knowledge and must be supplied explicitly.

### Added

- `useHreflangLinks(resource, builder)` composable — generic hreflang `<link>` injector that filters by the resource's `available_locales` and adds an `x-default` entry. Works for any CMS resource with `slug`, `available_locales`, and `localized_slugs` fields (articles, authors, future series, etc.). The `builder` callback decides URL paths, locale prefix strategy, trailing slash, and origin, so it adapts to any route structure without forking the package.

### Migration

If you previously relied on `useArticle`'s auto hreflang:

```ts
// 0.2.x — implicit, hardcoded /blog/{slug}
const { article } = useArticle(slug)

// 0.3.0 — explicit, consumer-defined URL pattern
const { article } = useArticle(slug)
useHreflangLinks(article, ({ locale, slug, resource }) => {
  const origin = `https://${siteUrl}`
  if (locale === 'x-default') return `${origin}/blog/${slug}`
  return `${origin}/${locale}/blog/${slug}`
})
```

Consumers using non-`/blog/` routes (e.g. marketing site `/{category}/{slug}/`) were silently outputting broken hreflang under 0.2.x and should migrate immediately.

## [0.2.1] - 2026-03-24

### Fixed

- Preview pages showing stale content after edits — Nitro SWR cache key now includes a unique timestamp for preview requests, ensuring each refresh bypasses the route-level SWR cache and renders fresh draft content

## [0.2.0] - 2026-03-24

### Added

- `useCmsPreviewToken()` composable — SWR-safe preview token reading (SSR reads from `event.context`, CSR reads from cookie)
- `preview-context` server middleware — copies preview cookie to `event.context` so it survives Nitro SWR synthetic events
- Preview redirect now appends `?_preview=1` for separate SWR cache key isolation (prevents draft content leaking to public cache)

### Fixed

- Preview 404 when Nitro SWR caching is enabled — SWR synthetic events strip all request headers including cookies, causing preview token loss during SSR rendering
- ISR revalidation cache key mismatch — `_revalidate.post.ts` now uses Nitro's internal key format (`escapeKey + hash`) with prefix matching instead of naive path-to-key conversion

## [0.1.0] - 2026-03-23

### Added

- ESLint flat config (`@antfu/eslint-config` + Vue) + Prettier

### Changed

- Codebase formatted with Prettier (singleQuote, no semi, printWidth 100)

## [0.0.1] - 2025-03-23

### Added

- Nuxt 3 module for CMS integration (`@vigilkids/cms-nuxt`)
- Auto-registered composables: `useCmsArticle`, `useCmsPreview`, `useCmsSitemap`
- Server API route for preview token validation with secure cookie
- Preview mode middleware with cookie-based authentication
- Sitemap provider integration with `@nuxtjs/sitemap`
- Runtime config integration for CMS API base URL
