Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Nuxt Content reads the `content/` directory in your project, parses `.md`, `.yml

- [📖  Read the documentation](https://content.nuxt.com)
- [✨  Intro video](https://www.youtube.com/watch?v=o9e12WbKrd8)
- [✍️  Nuxt Studio](https://content.nuxt.com/studio)
- [✍️  Nuxt Studio](https://content.nuxt.com/docs/studio/setup)

## Features

Expand Down
7 changes: 0 additions & 7 deletions docs/app/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,6 @@ export default defineAppConfig({
secondary: 'sky',
neutral: 'slate',
},
pageHero: {
slots: {
title: 'font-semibold sm:text-6xl',
description: 'sm:text-lg text-(--ui-text-toned) max-w-5xl mx-auto',
container: 'py-16 sm:py-20 lg:py-24',
},
},
pageSection: {
slots: {
title: 'font-semibold lg:text-4xl',
Expand Down
5 changes: 4 additions & 1 deletion docs/app/components/AppHeaderCTA.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
<template>
<UButton
v-if="$route.path == '/'"
label="Open Studio"
label="Open Legacy Studio"
color="neutral"
variant="subtle"
to="https://nuxt.studio"
size="sm"
class="hidden sm:inline-flex"
target="_blank"
/>
</template>
19 changes: 7 additions & 12 deletions docs/app/components/AppHeaderCenter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,16 @@ const links = computed(() => [
label: 'Documentation',
icon: 'i-lucide-book-open',
to: '/docs/getting-started',
active: route.path.startsWith('/docs'),
active: route.path.startsWith('/docs') && !route.path.startsWith('/docs/studio'),
}, {
label: 'Studio',
badge: {
label: 'alpha',
color: 'primary',
},
icon: 'i-lucide-file-pen-line',
children: [{
icon: 'i-lucide-mouse-pointer-click',
label: 'Features',
description: 'Everything you need to edit your Nuxt Content project',
to: '/studio',
}, {
label: 'Pricing',
description: 'Free for personal use, paid plans for teams',
icon: 'i-lucide-rocket',
to: '/studio/pricing',
}],
to: '/docs/studio/setup',
active: route.path.startsWith('/docs/studio'),
}, {
label: 'Templates',
icon: 'i-lucide-layout-template',
Expand Down
42 changes: 42 additions & 0 deletions docs/app/components/UInputCopy.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<script setup lang="ts">
defineProps({
value: {
type: String,
required: true,
},
size: {
type: String,
default: 'lg',
},
})
const { copy, copied } = useClipboard()
</script>

<template>
<label>
<UInput
:model-value="value"
:size="size"
disabled
:ui="{ trailing: 'pe-1', root: 'w-[245px]' }"
>
<div
class="absolute inset-0"
:class="[copied ? 'cursor-default' : 'cursor-copy']"
@click="copy(value)"
/>
<template #trailing>
<UButton
:icon="copied ? 'i-lucide-check' : 'i-lucide-copy'"
color="neutral"
variant="link"
:padded="false"
:ui="{ leadingIcon: 'size-4' }"
:class="{ 'text-green-500 hover:text-green-500 dark:text-green-400 hover:dark:text-green-400': copied }"
aria-label="copy button"
@click="copy(value)"
/>
</template>
</UInput>
</label>
</template>
26 changes: 7 additions & 19 deletions docs/app/pages/templates/[slug].vue
Original file line number Diff line number Diff line change
Expand Up @@ -86,25 +86,13 @@ const images = computed(() => template.value
:to="template.demo"
target="_blank"
/>

<UDropdownMenu
:items="[{
label: 'Import on Studio',
to: 'https://nuxt.studio/signin',
target: '_blank',
}, {
label: 'Clone on GitHub',
to: `https://github.com/${template.owner}/${template.name}/tree/${template.branch}`,
target: '_blank',
}]"
>
<UButton
label="Use it"
color="primary"
variant="solid"
trailing-icon="i-ph-arrow-right"
/>
</UDropdownMenu>
<UButton
label="Clone on GitHub"
color="primary"
variant="solid"
:to="`https://github.com/${template.owner}/${template.name}/tree/${template.branch}`"
trailing-icon="i-ph-arrow-right"
/>
</div>
</template>
</UPageHeader>
Expand Down
197 changes: 197 additions & 0 deletions docs/content/blog/studio-module-alpha.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
---
title: Nuxt Studio Alpha Release
authors:
- name: Baptiste Leproux
avatar:
src: https://avatars.githubusercontent.com/u/7290030?v=4
to: https://x.com/_larbish
username: larbish
- name: Ahad Birang
avatar:
src: https://avatars.githubusercontent.com/u/2047945?v=4
to: https://x.com/farnabaz
username: farnabaz
- name: Sébastien Chopin
avatar:
src: https://avatars.githubusercontent.com/u/904724?v=4
to: https://x.com/atinux
username: atinux
category: Release
date: 2025-11-04T00:00:00.000Z
description: Introducing the first alpha release of Nuxt Studio as a free, open-source Nuxt module. Edit your content in production with GitHub integration and real-time preview.
draft: false
image:
src: /blog/nuxt-studio-module-alpha.png
alt: Nuxt Studio Alpha Release
---

When NuxtLabs joined Vercel, we promised to transform [nuxt.studio](https://nuxt.studio) from a hosted platform into a free, open-source module. Today, we're excited to announce the **first alpha release** of the Nuxt Studio module.

::u-button{to="https://github.com/nuxt-content/studio" icon="i-simple-icons-github" target="_blank" color="neutral" variant="subtle"}
Discover the Nuxt Studio module on GitHub.
::

You can now enable content editing directly in production, with real-time preview and GitHub integration, all from within your own Nuxt application.

:video{controls loop src="https://res.cloudinary.com/nuxt/video/upload/v1733494722/contentv3final_rc8bvu.mp4"}

::u-button{to="/admin?redirect=/blog/studio-module-alpha" icon="i-lucide-mouse-pointer-click" external color="neutral" class="mt-4"}
Try editing this page
::

## 🏠 From Hosted Platform to Self-Hosted Module

This milestone wouldn't have been possible without Vercel's support. Their backing allowed us to dedicate the resources needed to rebuild Studio as an open-source module.

### What's Different?

Originally provided as a hosted platform at [nuxt.studio](https://nuxt.studio), Studio is now a free and open-source Nuxt module that you can deploy alongside your Nuxt Content website.

This means content editors can manage and update content directly in production, on their website, without the need of local development tools or Git knowledge.

- **Self-hosted** — runs entirely on your infrastructure alongside your Nuxt app
- **No external dependencies** — no APIs or third-party services required
- **Free and open-source** — released under the MIT license
- **Direct integration** — a simple GitHub OAuth app is needed to get started

The only trade-off is that Studio now requires a server-side route for authentication. While static generation remains supported with [Nuxt hybrid rendering](https://nuxt.com/docs/4.x/guide/concepts/rendering#hybrid-rendering), your site must be deployed on a platform that supports SSR.

## 📦 What's Shipped in Alpha

The alpha release focuses on **core infrastructure and stability** without risking any bugs introduced by the Visual editor. We're using Monaco editor to ensure all file operations and GitHub workflows are rock-solid before introducing visual editing.

**Monaco Code Editor** → IDE editing experience with syntax highlighting for Markdown, YAML, and JSON, including full MDC syntax support and split-screen diff viewer for conflicts.

**File Operations** → Complete CRUD operations for your `content/` directory. Create, edit, delete, rename, and move files with built-in draft management.

**Media Management** → Centralized library for assets in your `public/` directory with upload, organize, preview, and integrate capabilities.

**Git Integration** → Direct commits to GitHub via OAuth with conflict detection, author attribution, and custom commit messages.

**Real-time Preview** → Live preview of draft changes on your production website with instant updates and side-by-side editing.

## 🗺️ The Road Ahead

### Beta Release `Q4 2025`

Inspired from what we've built on [nuxt.studio](https://nuxt.studio), the beta phase will introduce the open-source visual editor, making Studio accessible to non-technical users:

- **Markdown Editor** — Notion-inspired experience for Markdown
- **Form-based Editing** — Schema-based forms for Markdown frontmatter, YAML, and JSON files
- **Vue Component Edition** — Visual interface for editing component props and slots
- **Google OAuth** — Alternative authentication for non-GitHub users

### Stable Release `End of Year 2025`

Production-ready features, performance optimizations, and enhanced stability.

::warning
At the end of year, the hosted platform will be sunset and the module will be the only way to edit your Nuxt Content website.
::

### Beyond `2026`

AI-powered content suggestions, multiple git providers, and community-driven features.

## 🗄️ Storage Architecture

Studio uses a three-tier storage architecture to keep content synchronized between your browser and GitHub.

### Production Database `SQLite WASM`

When your Nuxt Content website loads, Nuxt Content v3 downloads a SQLite database dump from your server and initializes a local WASM database containing all content from your deployed branch. This database stays in sync with GitHub as long as your last deployment completed successfully. This is the production database updated by Studio when you edit content.

### Draft Storage `IndexedDB`

Studio maintains a separate draft layer using [unstorage](https://unstorage.unjs.io/) backed by IndexedDB. When you edit content, changes are stored as drafts locally in your browser. Each time Studio loads, these drafts are merged with the SQLite database to render a drafted version of your production site.

::note
Drafts are stored only in your browser. They're not shared between editors or devices.
::

### GitHub Repository `API Integration`

When you publish, Studio commits your draft changes directly to GitHub through the GitHub API. Your CI/CD pipeline then rebuilds and redeploys your site automatically. After deployment, you'll need to refresh to update your browser database with the latest content.

## 🔄 The Sync Flow

### Initial Load

::prose-steps{level="4"}
#### Database Initialization

Nuxt Content downloads the SQLite database dump generated during the build process. :br
This file contains all parsed content from your `content/` directory.

#### Draft Recovery

Studio checks IndexedDB for any existing drafts from previous sessions and loads them into the SQLite database.

#### Preview

Studio refreshes the site preview so you can view your latest drafts and edits directly on your production website.
::

### Editing Content

::prose-steps{level="4"}
#### Draft Modification

Changes are saved immediately in IndexedDB as draft items with a status of `created`, `modified`, or `deleted`.

#### Database Update

The local SQLite database is updated to include your draft content, allowing instant visual preview.

#### Conflict Detection

Studio compares your draft content against the latest version on GitHub to detect possible conflicts.

:::note
**Conflicts can occur when:**

:br

- Someone pushes a commit that modifies the same file and its version is currently building.
- A deployment fails or hasn’t completed, leaving the production out of date and unsync with GitHub.
:::
::

### Publishing Changes

::prose-steps{level="4"}
#### Draft Collection

Studio gathers all draft items that contain changes.

#### GitHub Commit

Using the GitHub API, Studio creates a new commit with all updated files.

#### Deployment Trigger

Your CI/CD platform detects the commit and automatically rebuilds and redeploys your website.

#### Deployment Wait

After publication, Studio clears the local drafts and waits for the deployment to complete. :br
During this time, a loading state is shown while the production SQLite database catches up with your latest commit.

:::warning
Until your commit is deployed, Studio remains in a pending state where the production database is not yet up to date.
:::
::

## 🚀 Get Started Today

Install the module and configure your GitHub OAuth app to start editing content in production:

```bash
npx nuxi module add nuxt-studio
```

Check out the [setup guide](/docs/studio/setup) for complete installation and configuration instructions.

---

We're excited to see what you build with Nuxt Studio. Join the conversation on [GitHub Discussions](https://github.com/nuxt-content/studio/discussions) or [join our Discord](https://discord.gg/sBXDm6e8SP) to help shape the future of the module.
2 changes: 1 addition & 1 deletion docs/content/docs/1.getting-started/1.index.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ The new collections system provides automatic TypeScript types for all your data

### Nuxt Studio Integration :badge[Soon]{color="neutral"}

[Nuxt Studio](/docs/studio/setup) and v3 are designed to complement each other perfectly.. The [studio module](https://github.com/nuxtlabs/studio-module) is now integrated directly into Nuxt Content, creating an ideal environment where developers can focus on code while team members manage content through an intuitive interface.
[Nuxt Studio](/docs/studio/setup) and v3 are designed to complement each other perfectly.. The [studio module](https://github.com/nuxt-content/studio) is creating an ideal environment where developers can focus on code while team members manage content through an intuitive interface.

---

Expand Down
19 changes: 0 additions & 19 deletions docs/content/docs/1.getting-started/3.configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -500,25 +500,6 @@ export default defineNuxtConfig({
```
::

## `preview`

Enable `Preview API`

::prose-note
This is needed to enable live preview on [Nuxt Studio](/studio).
::

Value:

- `dev`: Enable in development mode
- `api`: Activate the preview mode and set the `API` to be linked with.

```ts [Enable Studio]
preview: {
api: 'https://api.nuxt.studio',
}
```

## `experimental`

Experimental features that are not yet stable.
Expand Down
16 changes: 0 additions & 16 deletions docs/content/docs/1.getting-started/4.migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,6 @@ The new API is backed by SQL and content queries happens within a specific colle
- Due to SQL limitations, sort order now uses alphabetical order instead for numerical order. Check out the [Ordering Files](/docs/collections/types#ordering-files) section for more information.
- Module options have changed from v2. Check out [configuration page](/docs/getting-started/configuration) for details.

### Nuxt Studio integration

- The [studio module](https://nuxt.studio) has been deprecated and a new generic `Preview API` has been implemented directly into Nuxt Content, you can remove the `@nuxthq/studio` package from your dependencies and from the `nuxt.config.ts` modules. Instead we just need to enable the preview mode in the Nuxt configuration file by binding the Studio API.

```ts [nuxt.config.ts]
export default defineNuxtConfig({
content: {
preview: {
api: 'https://api.nuxt.studio'
}
},
})
```

- In order to keep the [app config file](/docs/studio/config) updatable from Studio we just need to update the helper import of the `nuxt.schema.ts` file from `@nuxthq/studio/theme` to `@nuxt/content/preview`.

## Implement Document Driven mode in v3

Implementing document driven mode in Content v3 is quite easy. All you need is to create a catch-all page in Nuxt and fetch contents based on route path.
Expand Down
Loading
Loading