Back to blog
Blog

How to Build a Vue 3 App with a Headless CMS (Step-by-Step Tutorial)

Cosmic's avatar

Cosmic

April 01, 2026

How to Build a Vue 3 App with a Headless CMS (Step-by-Step Tutorial) - cover image

If you've been building Vue 3 apps and managing content in markdown files, Google Docs, or a tangled WordPress backend, a headless CMS is worth a serious look. It gives your content team a clean editing interface while giving you full control over how and where that content is rendered.

This tutorial walks through how to connect Cosmic to a Vue 3 app. By the end, you'll have a working Single File Component (SFC) that fetches and renders content from Cosmic, and you'll understand the core patterns for building content-driven Vue apps at scale.

Looking for a Vue-specific overview first? Check out our headless CMS for Vue page for a quick rundown of why Cosmic is a great fit for Vue projects.


Why use a headless CMS with Vue 3?

Vue 3 is a fantastic frontend framework, but it doesn't make opinions about where your content comes from. That's intentional. Headless CMSes fill that gap by providing:

  • A structured content API (REST or GraphQL) your Vue app can query
  • An editing UI for non-developers to manage content without touching code
  • Media handling, localization, and role-based access built in
  • Framework-agnostic delivery, so your content works in Vue, Nuxt, a mobile app, or anywhere else

This is exactly the pattern used by Vuetify, the popular Vue component library. They use Cosmic to manage their documentation and content, keeping their developer-facing content decoupled from their codebase.


What we're building

A Vue 3 app that:

  1. Connects to Cosmic via the official JavaScript SDK
  2. Fetches a list of blog posts (or any content type) from your Cosmic bucket
  3. Renders the posts in a Vue 3 SFC using the Composition API

Prerequisites

  • Node.js 18+
  • Basic familiarity with Vue 3 and the Composition API
  • A free Cosmic account (takes 30 seconds)

Step 1: Set up a Cosmic bucket

  1. Sign up at cosmicjs.com and create a new bucket.
  2. In your bucket, create an Object Type called with these metafields:
    • (text)
    • (auto-generated)
    • (rich text or markdown)
    • (file)
  3. Add a couple of sample posts so you have something to render.
  4. Go to Settings > API Keys and copy your Bucket Slug, Read Key.

Step 2: Create a Vue 3 project

If you don't have a project yet, scaffold one with Vite:



Step 3: Install the Cosmic SDK

Cosmic has an official JavaScript SDK that works in Node.js and the browser.



Step 4: Configure your environment variables

Create a file in the project root:


Never commit your read key to version control. Add to your .


Step 5: Create a Cosmic client module

Create :


This keeps your client configuration in one place. Every component that needs data imports from here.


Step 6: Build the Posts component

Create :


A few things worth calling out here:

  • limits which fields are returned by the API. Only request what you need. Smaller payloads mean faster load times.
  • sorts newest first. Prefix a field with for descending order.
  • is a built-in image transformation URL. Append query params like to resize and optimize images on the fly with no extra tooling.
  • / / handles all three states cleanly: loading, error, and data.

Step 7: Fetch a single post by slug

When a user clicks "Read more", you'll need to fetch the full post. Create :


Security note: Only use with content you control, like content you've authored in your own CMS. Never use it with raw user-submitted data.


Step 8: Wire it together in App.vue

Update to include your new component:


Run and open . Your posts from Cosmic should render immediately.


Using the REST API directly

Prefer to skip the SDK and use the REST API directly? That works too, and is a good option if you're on a tight bundle budget or already using a fetch wrapper.


Then use it in your component exactly as before, replacing the SDK call with .


Nuxt 3 bonus: server-side fetching

If you're using Nuxt 3, swap for to fetch content server-side:


This runs on the server, so content is included in the HTML response. Better SEO, faster first paint.


What to build next

You've got the core pattern down. Here are a few natural next steps:

  • Add Vue Router for client-side navigation between posts
  • Set up preview mode so editors can preview unpublished content before publishing
  • Use Cosmic's image transformation API for responsive images with srcset
  • Add content localization if you're building for multiple markets
  • Connect a Nuxt 3 project for full SSR and static generation support

Why Cosmic for Vue projects

Cosmic is built API-first, which means it works naturally with any JavaScript framework. There's no opinionated page router to fight, no plugin system to configure, and no CMS-specific templating language to learn. You get a clean JSON API and you build the frontend your way.

This is why teams like Vuetify have chosen Cosmic to manage their content. When your framework is already beloved by developers, your CMS should stay out of the way.

Explore the headless CMS for Vue page for more on how Cosmic fits into a Vue architecture.


Get started

Ready to try it yourself? Create a free Cosmic account and have a working Vue 3 integration running in minutes. The free plan includes everything you need to get started, with no credit card required.

Want to talk through your project? Book a quick intro with Tony, Cosmic's CEO, and get personalized advice for your use case.

Ready to get started?

Build your next project with Cosmic and start creating content faster.

No credit card required • 75,000+ developers