Choosing a CMS for a modern web project is about more than just the editing experience. It's about how the content model maps to your frontend, how you query it, and whether your editors will actually use it. After building several projects with Sanity, here's what I've learned.
Why Sanity?
Sanity positions itself as a "content platform" rather than just a CMS. The key differentiators that made me choose it over alternatives like Contentful or Strapi:
- Schema-as-code — your content model lives in TypeScript files, not a GUI
- GROQ — a powerful query language that feels natural for JSON documents
- Real-time collaborative editing with conflict resolution built-in
- Portable Text — a structured rich-text format that renders anywhere
- Self-hosted Studio — fully customisable admin panel you control
Integrating with SvelteKit
The Client Setup
The official @sanity/client package works seamlessly in SvelteKit's server-side load functions. The key is keeping your token server-side and using the CDN client for public reads:
GROQ Queries
GROQ (Graph-Relational Object Queries) takes some getting used to, but it's remarkably expressive. A typical query for a portfolio project list looks like:
"The best part of GROQ is the projection syntax — you specify exactly what fields to return, so you never over-fetch."
Portable Text Rendering
Portable Text is Sanity's answer to the rich-text storage problem. Instead of storing HTML, it stores a normalised block structure that you render with a library — in our case @portabletext/svelte.
Custom block renderers let you handle code blocks, images, and any custom types you define in your schema. The rendering is fully under your control.
Schema Design Tips
After building multiple projects with Sanity, these patterns have saved me the most time:
- Use
- Define a shared
- Use
- Keep your rich-text schemas tight — only enable block types you actually need
- Validation rules in your schema catch data issues before they reach the frontend
Performance Considerations
Sanity's CDN is fast, but for a portfolio site you want zero CMS latency on page loads. The solution is SvelteKit's server-side rendering with a short cache TTL:
With this setup, the first request fetches from Sanity and caches the result. Subsequent requests are served from edge cache until the TTL expires. For a portfolio site with infrequent content changes, a 60-second TTL is perfectly fine.
Final Thoughts
Sanity + SvelteKit is one of my favourite stacks right now. The type-safe schema, the expressive query language, and SvelteKit's flexible rendering modes make for a very pleasant development experience. The learning curve is real but shallow — most developers are productive within a day.

