Skip to content

Commit 5ed5e40

Browse files
committed
feat: suport seo and meta frontmatter, close #2, close #3
1 parent 1335284 commit 5ed5e40

File tree

7 files changed

+91
-86
lines changed

7 files changed

+91
-86
lines changed

README.md

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
[![License][license-src]][license-href]
77
[![Nuxt][nuxt-src]][nuxt-href]
88

9-
Nuxt Module to compile markdown files into Vue SFC at build time.
9+
Nuxt Module to compile markdown files into Vue SFC at **build time**. This enables you to put `.md` files into your `pages` directory as standalone pages, and `.md` under `components` directory as Vue components. With components auto-import built-in in Nuxt, you can also use any components in your markdown files.
1010

1111
## Install
1212

@@ -33,33 +33,11 @@ export default defineNuxtConfig({
3333
})
3434
```
3535

36-
That's it! You can now use My Module in your Nuxt app ✨
36+
## FAQ
3737

38-
## Development
38+
### How does this compare to [@nuxt/content](https://content.nuxtjs.org/)?
3939

40-
```bash
41-
# Install dependencies
42-
npm install
43-
44-
# Generate type stubs
45-
npm run dev:prepare
46-
47-
# Develop with the playground
48-
npm run dev
49-
50-
# Build the playground
51-
npm run dev:build
5240

53-
# Run ESLint
54-
npm run lint
55-
56-
# Run Vitest
57-
npm run test
58-
npm run test:watch
59-
60-
# Release new version
61-
npm run release
62-
```
6341

6442
<!-- Badges -->
6543
[npm-version-src]: https://img.shields.io/npm/v/nuxt-compile-markdown/latest.svg?style=flat&colorA=18181B&colorB=28CF8D

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
},
3131
"dependencies": {
3232
"@nuxt/kit": "^3.6.5",
33-
"unplugin-vue-markdown": "^0.24.1"
33+
"unplugin-vue-markdown": "^0.24.2"
3434
},
3535
"devDependencies": {
3636
"@antfu/eslint-config": "^0.40.2",
@@ -42,6 +42,6 @@
4242
"changelogen": "^0.5.4",
4343
"eslint": "^8.47.0",
4444
"nuxt": "^3.6.5",
45-
"vitest": "^0.34.1"
45+
"vitest": "^0.34.2"
4646
}
4747
}

playground/app.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
<template>
2-
<NuxtPage />
2+
<NuxtLayout>
3+
<NuxtPage />
4+
</NuxtLayout>
35
</template>

playground/pages/blog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ title: Blog
33
seo:
44
title: 'Welcome to my blog'
55
description: 'A list of article about Vue & Nuxt'
6+
ogImage: https://nuxt.com/social.jpg
67
meta:
78
layout: dark
89
middleware: log

playground/pages/index.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
---
2+
title: Home!
3+
---
4+
15
# Hello
26

37
Nuxt Page as Markdown

pnpm-lock.yaml

Lines changed: 32 additions & 32 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/module.ts

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { addVitePlugin, addWebpackPlugin, defineNuxtModule } from '@nuxt/kit'
2-
import type { Options } from 'unplugin-vue-markdown/types'
2+
import type { Options as MarkdownOptions } from 'unplugin-vue-markdown/types'
33
import Markdown from 'unplugin-vue-markdown'
44

5-
export interface ModuleOptions extends Options { }
5+
export interface ModuleOptions extends MarkdownOptions { }
66

77
export default defineNuxtModule<ModuleOptions>({
88
meta: {
@@ -51,37 +51,57 @@ export default defineNuxtModule<ModuleOptions>({
5151
nuxt.options.vite.vue.include.push(reEndingOrQuery)
5252
}
5353

54-
options.include = [reEndingOrQuery]
5554
const originalMarkdownItSetup = options.markdownItSetup
56-
options.markdownItSetup = async (md) => {
57-
await originalMarkdownItSetup?.(md)
55+
const resolvedOptions: MarkdownOptions = {
56+
wrapperClasses: '',
57+
...options,
58+
include: [reEndingOrQuery],
59+
headEnabled: false,
60+
async markdownItSetup(md) {
61+
await originalMarkdownItSetup?.(md)
5862

59-
// Replace <a> with <NuxtLink>
60-
md.core.ruler.push(
61-
'NuxtLink',
62-
(state) => {
63-
type Token = (typeof state.tokens)[0]
64-
function visit(token: Token) {
65-
if (token.tag === 'a') {
66-
token.tag = 'NuxtLink'
67-
// Replace `href` with `to`
68-
const hrefTag = token.attrs?.find(([name]) => name === 'href')
69-
if (hrefTag)
70-
hrefTag[0] = 'to'
63+
// Replace <a> with <NuxtLink>
64+
md.core.ruler.push(
65+
'NuxtLink',
66+
(state) => {
67+
type Token = (typeof state.tokens)[0]
68+
function visit(token: Token) {
69+
if (token.tag === 'a') {
70+
token.tag = 'NuxtLink'
71+
// Replace `href` with `to`
72+
const hrefTag = token.attrs?.find(([name]) => name === 'href')
73+
if (hrefTag)
74+
hrefTag[0] = 'to'
75+
}
76+
token.children?.forEach(visit)
7177
}
72-
token.children?.forEach(visit)
78+
79+
state.tokens.forEach(visit)
80+
},
81+
)
82+
},
83+
84+
transforms: {
85+
extraScripts(frontmatter) {
86+
const scripts: string[] = []
87+
88+
if (frontmatter.meta)
89+
scripts.push(`definePageMeta(${JSON.stringify(frontmatter.meta)})`)
90+
91+
if (frontmatter.seo || frontmatter.title || frontmatter.description) {
92+
scripts.push(`useSeoMeta(${JSON.stringify({
93+
...frontmatter.title ? { title: frontmatter.title } : {},
94+
...frontmatter.description ? { description: frontmatter.description } : {},
95+
...frontmatter.seo,
96+
})})`)
7397
}
7498

75-
state.tokens.forEach(visit)
99+
return scripts
76100
},
77-
)
101+
},
78102
}
79103

80-
options.wrapperClasses = options.wrapperClasses || ''
81-
// Force disabling head (leveraging `seo` key)
82-
options.headEnabled = false
83-
84-
addVitePlugin(() => Markdown.vite(options))
85-
addWebpackPlugin(() => Markdown.webpack(options))
104+
addVitePlugin(() => Markdown.vite(resolvedOptions))
105+
addWebpackPlugin(() => Markdown.webpack(resolvedOptions))
86106
},
87107
})

0 commit comments

Comments
 (0)