TwoSlash integrations for Nuxt Content.
nuxt-content-twoslash module to your project:pnpm add nuxt-content-twoslash
#
yarn add nuxt-content-twoslash
#
npm install nuxt-content-twoslash
modules section in your nuxt.config, before @nuxt/content:// nuxt.config.js
export default defineNuxtConfig({
modules: [
'nuxt-content-twoslash', // this needs to be before `@nuxt/content`
'@nuxt/content'
],
content: {
// ...
},
twoslash: {
// ...
}
})
To start using Twoslash in your Nuxt Content markdown files, you will need to add twoslash within your markdown code block tag.
Try out the below code snippet and watch the magic happen.
```ts twoslash
import { ref } from 'vue'
const message = ref('Hello')
```
```vue twoslash
<script setup>
import { ref } from 'vue'
// Reactive state.
const count = ref(0)
</script>
<template>
<button>Count is: {{ count }}</button>
</template>
```
For more advanced usage, please see the Twoslash Notations.
Nuxt Content uses Shiki under the hood via the Nuxt MDC module. This module injects a Shiki transformer based on @shikijs/twoslash to leverage Twoslash (which invokes a TypeScript server) to get the type information while also validating the type safety.
With Nuxt Content’s cache mechanism, Twoslash will run only once at build time and pre-render phrase. The generated type information will be served as static content and shipped with your app. So there would be no runtime overhead.
By default, this module will try to read the types generated by Nuxt and the tsconfig.json under .nuxt directory and inject them into TwoSlash context. Ideally this would make your code snippets works behave closer to your local dev environment.
If you don’t want this behavior, you can disable it by setting twoslash.injectNuxtTypes to false in the module options.
Nuxt v4 uses TypeScript project references, which split your project into separate type contexts: app, server, node, and shared. Each context has its own tsconfig with different compiler options, path mappings, and available auto-imports.
This module automatically detects Nuxt v4 project references and resolves the correct type context for each code block. To specify which context a code block belongs to, use the [filename] syntax in the code block meta:
### Server code (server context)
```ts twoslash [server/api/hello.ts]
import { defineEventHandler } from 'h3'
export default defineEventHandler(() => {
return { status: 'ok' }
})
```
### Nuxt config (node context)
```ts twoslash [nuxt.config.ts]
export default defineNuxtConfig({
modules: ['@nuxt/content'],
})
```
### App code (app context)
```ts twoslash [app/app.vue]
const count = ref(0)
const route = useRoute()
```
### Shared code (shared context)
```ts twoslash [shared/utils/format.ts]
export function formatDate(date: Date) {
return date.toISOString()
}
```
The [filename] is matched against each context’s tsconfig include/exclude patterns to determine which type environment to use. Code blocks without a [filename] fall back to the default (combined) type context.
Context matching follows a priority order: node > app > shared > server, to handle cases where patterns overlap.
This module also provides a command-line interface to verify TwoSlash code snippets in your markdown files, where you can guard the type safety in continuous integration.
npx nuxt-content-twoslash verify
The CLI automatically detects Nuxt projects (by looking for nuxt.config.ts or nuxt.config.js) and resolves type information from your .nuxt build directory. It also fully supports Nuxt v4 project references, automatically picking up the context-specific tsconfig files and validating each code block against the correct type environment.
[!TIP]
An example usage is that in nuxt/nuxt.com, we load the docs externally from nuxt/nuxt repository. This way it allows the docs to be closer to the source code and easier for contributors to update them in the same PR.
To support that seperation while able to make sure code snippets in nuxt/nuxt are type safe, we use this CLI in the CI to verify the code snippets.
We use cookies
We use cookies to analyze traffic and improve your experience. You can accept or reject analytics cookies.