├── .babelrc ├── .editorconfig ├── .eslintrc.js ├── .github └── semantic.yml ├── .gitignore ├── README.md ├── components ├── Button │ ├── Button.vue │ └── index.js ├── Count │ ├── Count.vue │ └── index.js ├── LiveEditor │ ├── Layout.vue │ ├── LiveEditor.js │ └── index.js ├── Navbar │ ├── Navbar.vue │ └── index.js └── index.js ├── docs ├── documentation.mdx └── index.vue ├── jsconfig.json ├── layouts └── default.vue ├── nuxt.config.js ├── package.json ├── plugins └── live-editor.js ├── router.js ├── scss └── night-owl.css ├── static └── favicon.ico └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@vue/babel-preset-jsx" 4 | ], 5 | "plugins": [] 6 | } 7 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | browser: true, 5 | node: true 6 | }, 7 | parserOptions: { 8 | parser: 'babel-eslint' 9 | }, 10 | extends: [ 11 | '@nuxtjs', 12 | 'plugin:nuxt/recommended' 13 | ], 14 | // add your custom rules here 15 | rules: { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.github/semantic.yml: -------------------------------------------------------------------------------- 1 | # Always validate the PR title AND all the commits 2 | titleAndCommits: true 3 | # Allows use of Merge commits (eg on github: "Merge branch 'master' into feature/ride-unicorns") 4 | # this is only relevant when using commitsOnly: true (or titleAndCommits: true) 5 | allowMergeCommits: true 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Node template 3 | # Logs 4 | /logs 5 | *.log 6 | npm-debug.log* 7 | yarn-debug.log* 8 | yarn-error.log* 9 | 10 | # Runtime data 11 | pids 12 | *.pid 13 | *.seed 14 | *.pid.lock 15 | 16 | # Directory for instrumented libs generated by jscoverage/JSCover 17 | lib-cov 18 | 19 | # Coverage directory used by tools like istanbul 20 | coverage 21 | 22 | # nyc test coverage 23 | .nyc_output 24 | 25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 26 | .grunt 27 | 28 | # Bower dependency directory (https://bower.io/) 29 | bower_components 30 | 31 | # node-waf configuration 32 | .lock-wscript 33 | 34 | # Compiled binary addons (https://nodejs.org/api/addons.html) 35 | build/Release 36 | 37 | # Dependency directories 38 | node_modules/ 39 | jspm_packages/ 40 | 41 | # TypeScript v1 declaration files 42 | typings/ 43 | 44 | # Optional npm cache directory 45 | .npm 46 | 47 | # Optional eslint cache 48 | .eslintcache 49 | 50 | # Optional REPL history 51 | .node_repl_history 52 | 53 | # Output of 'npm pack' 54 | *.tgz 55 | 56 | # Yarn Integrity file 57 | .yarn-integrity 58 | 59 | # dotenv environment variables file 60 | .env 61 | 62 | # parcel-bundler cache (https://parceljs.org/) 63 | .cache 64 | 65 | # next.js build output 66 | .next 67 | 68 | # nuxt.js build output 69 | .nuxt 70 | 71 | # Nuxt generate 72 | dist 73 | 74 | # vuepress build output 75 | .vuepress/dist 76 | 77 | # Serverless directories 78 | .serverless 79 | 80 | # IDE / Editor 81 | .idea 82 | 83 | # Service worker 84 | sw.* 85 | 86 | # macOS 87 | .DS_Store 88 | 89 | # Vim swap files 90 | *.swp 91 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ⚡️ Nuxt + MDX Documentation 2 | 3 | > Demo project using MDX for documentation 4 | 5 | [**Netlify Demo**](https://nuxt-mdx.netlify.com) 6 | 7 | ### Features 8 | - SSR 9 | - Markdown documentation 10 | - Live Code Editor 11 | -------------------------------------------------------------------------------- /components/Button/Button.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 32 | -------------------------------------------------------------------------------- /components/Button/index.js: -------------------------------------------------------------------------------- 1 | import Button from './Button' 2 | export default Button 3 | -------------------------------------------------------------------------------- /components/Count/Count.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 45 | -------------------------------------------------------------------------------- /components/Count/index.js: -------------------------------------------------------------------------------- 1 | import Count from './Count' 2 | export default Count 3 | -------------------------------------------------------------------------------- /components/LiveEditor/Layout.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 39 | -------------------------------------------------------------------------------- /components/LiveEditor/LiveEditor.js: -------------------------------------------------------------------------------- 1 | import '@/scss/night-owl.css' 2 | import 'vue-prism-editor/dist/VuePrismEditor.css' 3 | import Layout from './Layout.vue' 4 | 5 | /** 6 | * Live Code Editor 7 | */ 8 | const LiveEditor = { 9 | name: 'LiveEditor', 10 | render (h) { 11 | const children = this.$slots.default[0] 12 | const innerText = children.text.trim() 13 | return h('VueLive', { 14 | props: { 15 | code: innerText, 16 | layout: Layout 17 | } 18 | }) 19 | } 20 | } 21 | 22 | export default LiveEditor 23 | -------------------------------------------------------------------------------- /components/LiveEditor/index.js: -------------------------------------------------------------------------------- 1 | import LiveEditor from './LiveEditor' 2 | export default LiveEditor 3 | -------------------------------------------------------------------------------- /components/Navbar/Navbar.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 31 | 32 | 51 | -------------------------------------------------------------------------------- /components/Navbar/index.js: -------------------------------------------------------------------------------- 1 | import Navbar from './Navbar.vue' 2 | export default Navbar 3 | -------------------------------------------------------------------------------- /components/index.js: -------------------------------------------------------------------------------- 1 | export { default as LiveEditor } from './LiveEditor' 2 | export { default as Navbar } from './Navbar' 3 | -------------------------------------------------------------------------------- /docs/documentation.mdx: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Count from '../components/Count' 3 | import { LiveEditor } from '../components' 4 | import Button from '../components/Button' 5 | Vue.component('Button', Button) 6 | 7 | # Vue Live Editor Example 8 | 9 | 10 | # `Demo` example 11 | 12 | 13 | {` 14 | 25 | 50 | 51 | 70 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "paths": { 5 | "~/*": ["./*"], 6 | "@/*": ["./*"], 7 | "~~/*": ["./*"], 8 | "@@/*": ["./*"] 9 | } 10 | }, 11 | "exclude": ["node_modules", ".nuxt", "dist"] 12 | } 13 | -------------------------------------------------------------------------------- /layouts/default.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 15 | 16 | 42 | -------------------------------------------------------------------------------- /nuxt.config.js: -------------------------------------------------------------------------------- 1 | 2 | export default { 3 | mode: 'universal', 4 | generate: { 5 | routes: [ 6 | '/', 7 | '/docs' 8 | ] 9 | }, 10 | head: { 11 | title: process.env.npm_package_name || '', 12 | meta: [ 13 | { charset: 'utf-8' }, 14 | { name: 'viewport', content: 'width=device-width, initial-scale=1' }, 15 | { hid: 'description', name: 'description', content: process.env.npm_package_description || '' } 16 | ], 17 | link: [ 18 | { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' } 19 | ] 20 | }, 21 | loading: { color: '#0092ff' }, 22 | plugins: [ 23 | { 24 | src: 'plugins/live-editor.js', 25 | ssr: false 26 | } 27 | ], 28 | buildModules: [ 29 | '@nuxtjs/eslint-module', 30 | '@nuxtjs/router' 31 | ], 32 | transition: 'fade', 33 | build: { 34 | extend (config, ctx) { 35 | config.resolve.alias.vue = 'vue/dist/vue.common' 36 | config.module.rules.push({ 37 | test: /\.mdx$/, 38 | use: [ 39 | 'babel-loader', 40 | { 41 | loader: '@mdx-js/vue-loader' 42 | } 43 | ] 44 | }) 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nuxt-mdx-poc", 3 | "version": "1.0.0", 4 | "description": "My breathtaking Nuxt.js project", 5 | "author": "codebender828", 6 | "private": true, 7 | "scripts": { 8 | "dev": "nuxt", 9 | "build": "nuxt build", 10 | "start": "nuxt start", 11 | "generate": "nuxt generate", 12 | "lint": "eslint --ext .js,.vue --ignore-path .gitignore ." 13 | }, 14 | "lint-staged": { 15 | "*.{js,vue}": "yarn lint" 16 | }, 17 | "husky": { 18 | "hooks": { 19 | "pre-commit": "lint-staged" 20 | } 21 | }, 22 | "dependencies": { 23 | "@mdx-js/vue-loader": "^1.5.5", 24 | "@nuxtjs/router": "^1.5.0", 25 | "nuxt": "^2.0.0", 26 | "vue-live": "^1.5.1" 27 | }, 28 | "devDependencies": { 29 | "@nuxtjs/eslint-config": "^2.0.0", 30 | "@nuxtjs/eslint-module": "^1.0.0", 31 | "@vue/babel-preset-jsx": "^1.1.2", 32 | "babel-eslint": "^10.0.1", 33 | "babel-loader": "^8.0.6", 34 | "eslint": "^6.1.0", 35 | "eslint-plugin-nuxt": ">=0.4.2", 36 | "husky": "^4.0.0", 37 | "lint-staged": "^10.0.0" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /plugins/live-editor.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueLive from 'vue-live' 3 | import { LiveEditor } from '@/components' 4 | 5 | Vue.use(VueLive) 6 | 7 | Vue.component('LiveEditor', LiveEditor) 8 | 9 | Vue.component('Wrapper', { 10 | render (h) { 11 | return h('div', this.$slots.default) 12 | } 13 | }) 14 | 15 | Vue.component('InlineCode', { 16 | render (h) { 17 | return h('code', this.$slots.default) 18 | } 19 | }) 20 | -------------------------------------------------------------------------------- /router.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | 4 | import Index from './docs/index.vue' 5 | import Docs from './docs/documentation.mdx' 6 | 7 | Vue.use(Router) 8 | 9 | export function createRouter () { 10 | return new Router({ 11 | mode: 'history', 12 | routes: [ 13 | { 14 | path: '/', 15 | component: Index 16 | }, 17 | { 18 | path: '/docs', 19 | component: Docs 20 | } 21 | ] 22 | }) 23 | } 24 | -------------------------------------------------------------------------------- /scss/night-owl.css: -------------------------------------------------------------------------------- 1 | code[class*=language-], 2 | pre[class*=language-] { 3 | color: #d6deeb; 4 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; 5 | text-align: left; 6 | white-space: pre; 7 | word-spacing: normal; 8 | word-break: normal; 9 | word-wrap: normal; 10 | line-height: 1.5; 11 | -moz-tab-size: 4; 12 | -o-tab-size: 4; 13 | tab-size: 4; 14 | -webkit-hyphens: none; 15 | -moz-hyphens: none; 16 | -ms-hyphens: none; 17 | hyphens: none 18 | } 19 | 20 | code[class*=language-] ::-moz-selection, 21 | code[class*=language-]::-moz-selection, 22 | pre[class*=language-] ::-moz-selection, 23 | pre[class*=language-]::-moz-selection { 24 | text-shadow: none; 25 | background: rgba(29, 59, 83, .99) 26 | } 27 | 28 | code[class*=language-] ::selection, 29 | code[class*=language-]::selection, 30 | pre[class*=language-] ::selection, 31 | pre[class*=language-]::selection { 32 | text-shadow: none; 33 | background: rgba(29, 59, 83, .99) 34 | } 35 | 36 | @media print { 37 | 38 | code[class*=language-], 39 | pre[class*=language-] { 40 | text-shadow: none 41 | } 42 | } 43 | 44 | pre { 45 | padding: 1em; 46 | margin: .5em 0; 47 | overflow: auto 48 | } 49 | 50 | :not(pre)>code, 51 | pre { 52 | color: #fff; 53 | background: #011627 54 | } 55 | 56 | :not(pre)>code { 57 | padding: .1em; 58 | border-radius: .3em; 59 | white-space: normal 60 | } 61 | 62 | .token.cdata, 63 | .token.comment, 64 | .token.prolog { 65 | color: #637777; 66 | font-style: italic 67 | } 68 | 69 | .token.punctuation { 70 | color: #c792ea 71 | } 72 | 73 | .namespace { 74 | color: #b2ccd6 75 | } 76 | 77 | .token.deleted { 78 | color: rgba(239, 83, 80, .56); 79 | font-style: italic 80 | } 81 | 82 | .token.property, 83 | .token.symbol { 84 | color: #80cbc4 85 | } 86 | 87 | .token.keyword, 88 | .token.operator, 89 | .token.tag { 90 | color: #7fdbca 91 | } 92 | 93 | .token.boolean { 94 | color: #ff5874 95 | } 96 | 97 | .token.number { 98 | color: #f78c6c 99 | } 100 | 101 | .token.builtin, 102 | .token.char, 103 | .token.constant, 104 | .token.function { 105 | color: #82aaff 106 | } 107 | 108 | .token.doctype, 109 | .token.selector { 110 | color: #c792ea; 111 | font-style: italic 112 | } 113 | 114 | .token.attr-name, 115 | .token.inserted { 116 | color: #addb67; 117 | font-style: italic 118 | } 119 | 120 | .language-css .token.string, 121 | .style .token.string, 122 | .token.entity, 123 | .token.string, 124 | .token.url { 125 | color: #addb67 126 | } 127 | 128 | .token.atrule, 129 | .token.attr-value, 130 | .token.class-name { 131 | color: #ffcb8b 132 | } 133 | 134 | .token.important, 135 | .token.regex, 136 | .token.variable { 137 | color: #d6deeb 138 | } 139 | 140 | .token.bold, 141 | .token.important { 142 | font-weight: 700 143 | } 144 | 145 | .token.italic { 146 | font-style: italic 147 | } 148 | -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebender828/nuxt-mdx-poc/dc5e72807decf8fda47635690abf1284a057a6de/static/favicon.ico --------------------------------------------------------------------------------