Studio

Edit your content

Discover and select your favorite way to manage your content between the visual or the code editor.
Alpha Release - TipTap Visual Editor Now Available!
The alpha version now includes both the Monaco code editor and the TipTap visual editor for Markdown files. You can switch between them at any time using the editor mode toggle in the toolbar.

Nuxt Studio offers a versatile workspace for both developers and content writers, giving them the freedom to choose between our different editors:

  • Notion-like editor for Markdown files
  • Form editor for YAML and JSON files
  • Code editor for any kind of files (for technical users only) Each editor serves its own purpose. Some users prefer visual editing, while others prefer direct code manipulation. At the end, Markdown and MDC syntax is the final output for both editors, with seamless conversion between visual and code modes.

Editor Mode Switching

You can switch between the visual editor and code editor at any time by clicking the actions dropdown in the toolbar:

  • Visual Mode (TipTap) - Notion-like editing experience
  • Code Mode (Monaco) - Direct Markdown/MDC syntax editing

Your preference is saved and will be used for all Markdown files.

TipTap Visual Editor (Markdown files)

The TipTap visual editor provides a modern Notion-like editing experience for Markdown content, powered by the popular TipTap editor integrated by Nuxt UI Editor.

Key Features

  • Rich Text Editing - Format text with headings, bold, italic, strikethrough, code, links, and more
  • MDC Component Support - Insert and edit custom Vue components directly in the visual editor
  • Media Integration - Browse in media picker to insert images from your library
  • Slash Commands - Type / to access a menu of formatting options and components
  • Drag & Drop - Reorder content blocks by dragging them
  • Link Editor - Floating popover for editing links with external link support
  • Toolbar - Bubble toolbar appears when you select text, providing quick access to formatting options
  • Real-time Conversion - Seamlessly converts between visual content and MDC/Markdown syntax

Debug Mode

Enable debug mode from the footer menu to see the real-time conversion between:

  • TipTap JSON format
  • MDC AST
  • Final Markdown output

This is useful for understanding how content is transformed and to share troubleshooting.

Code Editor

The Monaco code editor provides full control over your content, allowing you to write raw content directly:

Working with Vue Components

One of the TipTap visual editor's standout features is its ability to integrate and edit custom Vue components directly within the editor interface.

Create and Integrate Custom Components

Developers can create visually complex components, and editors can use them without technical knowledge. The visual editor handles component integration seamlessly.

Create your component

Vue components need to be located in the /components/content folder to be available in Studio:

components/content/HomeFeature.vue
<template>
  <div class="flex items-start gap-3">
    <div class="flex items-center justify-center border rounded-lg p-1.5">
      <UIcon :name="icon" />
    </div>
    <div class="flex flex-col">
      <h3 class="font-semibold">
        <slot name="title" />
      </h3>
      <span>
        <slot name="description" />
      </span>
    </div>
  </div>
</template>

<script setup lang="ts">
defineProps({
  icon: {
    type: String,
    default: 'i-lucide-cursor-click',
  },
})
</script>

Use in Markdown with MDC syntax

Components can be integrated using MDC syntax:

content/index.md
::home-feature
  ---
  icon: i-mdi-vuejs
  ---
  #title
  Embedded Vue components
  #description
  Edit slots and props inside the visual editor.
::

Edit in the Visual Editor

All components in the /components/content folder are automatically available:

  1. Type / anywhere while editing
  2. Search for your component in the list
  3. Insert and edit component slots directly in the editor
  4. Props editing with visual interface coming in beta
Enable debug mode to validate your Vue component integration in local development.

Integrate External Library Components

By default, components from external libraries (like Nuxt UI) won't appear in Studio's component list. To make them available, set them as global in your Nuxt config:

export default defineNuxtConfig({
  hooks: {
    'components:extend': (components) => {
      const globals = components.filter(c => ['UButton', 'UIcon'].includes(c.pascalName))

      globals.forEach(c => c.global = true)
    }
  },
})

Form Editor (Coming in Beta)

Coming in Beta
The form editor for frontmatter, YAML, and JSON files is currently under development and will be available in the beta release.

The form editor will be used for editing:

  • Frontmatter in Markdown files
  • YAML files
  • JSON files

It will eliminate the need to interact directly with complex file syntax. Instead, forms will be automatically generated based on your collection schema definition.

Defining your form with zod Schema

Learn more about schema collection definition in the dedicated section.

Once the schema property has been defined in your collection, this will automatically generate the corresponding form on Studio interface.

export default defineContentConfig({
  collections: {
    posts: defineCollection({
      type: 'page',
      source: 'blog/*.md',
      schema: z.object({
        draft: z.boolean().default(false),
        category: z.enum(['Alps', 'Himalaya', 'Pyrenees']).optional(),
        date: z.date(),
        image: z.object({
          src: property(z.string()).editor({ input: 'media' }),
          alt: z.string(),
        }),
        slug: property(z.string()).editor({ hidden: true }),
        icon: property(z.string().optional()).editor({ input: 'icon' }),
        authors: z.array(z.object({
          slug: z.string(),
          username: z.string(),
          name: z.string(),
          to: z.string(),
          avatar: z.object({
            src: z.string(),
            alt: z.string(),
          }),
        })),
      }),
    }),
  },
})

Native Inputs Mapping

Primitive Zod types are automatically mapped to appropriate form inputs in:

  • String → Text input
  • Date → Date picker
  • Number → Number input (counter)
  • Boolean → Toggle switch
  • Enum → Select dropdown
  • Arrays of strings → List of badge inputs
  • Arrays of objects → Accordion of items with embedded form

Custom Inputs Mapping

Studio goes beyond primitive types. You can customise form fields using the editor method, which extends Zod types with metadata to empower editor interface.

This allows you to define custom inputs or hide fields.

Usage

content.config.ts
// Icon
icon: property(z.string()).editor({ input: 'icon', iconLibraries: ['lucide', 'simple-icons'] })

// Media
image: property(z.string()).editor({ input: 'media' })

Options

input: 'media' | 'icon'

You can set the editor input type. Currently icon and media are available.

iconLibraries: Array<string>

Specifies which Iconify libraries to display. Use this option to filter and limit the available icon sets.

hidden: Boolean

This option can be set to avoid the display of a field in the Studio editor.

Studio inputs are fully extensible. We can create as many input as we want based on our users needs.