Skip to content

refactor(content): introduce typed ContentRepository abstraction#132

Merged
TheMeinerLP merged 2 commits into
mainfrom
claude/content-abstraction-layer-io8Pu
May 16, 2026
Merged

refactor(content): introduce typed ContentRepository abstraction#132
TheMeinerLP merged 2 commits into
mainfrom
claude/content-abstraction-layer-io8Pu

Conversation

@TheMeinerLP
Copy link
Copy Markdown
Collaborator

Summary

This PR introduces a provider-agnostic content access layer (ContentRepository) to decouple the application from @nuxt/content implementation details. All content queries are now funnelled through a single adapter, making it straightforward to swap content backends in the future without touching composables or pages.

Key Changes

  • New abstraction layer: Created ContentRepository interface (utils/content/repository.ts) defining all content access contracts (blog articles, FAQ, team, home, sponsors)
  • Adapter implementation: Implemented createNuxtContentAdapter() (utils/content/nuxtContentAdapter.ts) as the @nuxt/content-backed concrete implementation, encapsulating all collection-key naming and query syntax
  • Composable factory: Added useContentRepository() composable that returns the active adapter instance — the single point where content backend decisions are made
  • Refactored composables: Updated all content-accessing composables to depend on ContentRepository instead of direct queryCollection calls:
    • useBlogContent.ts: Replaced direct queries with repo.listBlogArticles(), repo.getBlogArticleBySlug(), repo.getBlogArticleByTranslationKey(), repo.getAuthorBySlug()
    • useHomeContent.ts: Simplified to use repo.getServerConcept(), repo.getServerConnect(), repo.getHomeCarousel()
    • useFaqContent.ts: Now uses repo.listFaqEntries()
    • useTeamProfile.ts: Refactored to use repo.getTeamDocument()
    • useSponsoring.ts: Updated to use repo.getSponsorsDocument()
  • Type improvements:
    • Introduced Locale type (utils/content/collections.ts) for type-safe locale handling
    • Created FaqEntry domain type (types/faq.ts) to replace inline interface
    • Removed @nuxt/content module augmentation from composables
  • Code cleanup: Extracted helper functions (isLocaleObject), improved formatting, and simplified computed properties

Implementation Details

  • The adapter is a stateless module-level singleton, safe for both SSR and client rendering
  • All @nuxt/content-specific details (collection-key naming like blog_de, query syntax) are confined to nuxtContentAdapter.ts
  • Domain logic (i18n resolution, filtering, sorting, SEO assembly) intentionally remains in composables — it's provider-independent
  • Switching to a headless CMS later requires only writing a new adapter; no composable/page changes needed
  • The FaqEntry type retains PageCollectionItemBase coupling at the rendering layer (for <ContentRenderer>), which a future CMS adapter would need to handle

https://claude.ai/code/session_01JM95TEbXcXrQignrX6J7mm

Decouple composables from @nuxt/content so the content backend can be
swapped for a headless CMS later without touching composables, pages or
components.

- Add provider-agnostic ContentRepository interface (utils/content/repository.ts)
- Add NuxtContentAdapter encapsulating all queryCollection calls,
  collection-key naming and content-specific casts (utils/content/nuxtContentAdapter.ts)
- Add useContentRepository() as the single backend swap point
- Move FaqEntry into a dedicated domain type (types/faq.ts)
- Route useBlogContent/useHomeContent/useFaqContent/useSponsoring/useTeamProfile
  through the repository; domain logic (i18n, release filtering, SEO/hreflang)
  stays in the composables

Also removes a stale @nuxt/content module augmentation, fixing 4
pre-existing type errors.

https://claude.ai/code/session_01JM95TEbXcXrQignrX6J7mm
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 16, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
launchpad dfd3277 Commit Preview URL

Branch Preview URL
May 16 2026, 10:47 AM

…ction-layer-io8Pu

# Conflicts:
#	composables/useBlogContent.ts
@cloudflare-workers-and-pages
Copy link
Copy Markdown

Deploying launchpad with  Cloudflare Pages  Cloudflare Pages

Latest commit: dfd3277
Status:⚡️  Build in progress...

View logs

@TheMeinerLP TheMeinerLP changed the title Introduce ContentRepository abstraction layer for content access refactor(content): introduce typed ContentRepository abstraction May 16, 2026
@TheMeinerLP TheMeinerLP merged commit 34c5bef into main May 16, 2026
4 of 5 checks passed
@TheMeinerLP TheMeinerLP deleted the claude/content-abstraction-layer-io8Pu branch May 16, 2026 11:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants