| search | english |
|---|
Writing docs without build process.
docute is a .js file along with its theme assets, which you can add to a static .html file hosted anywhere.
No extra setup for docute is needed, no build process, everything is performed on the fly! We're using a fork of marked the gorgeous and blazing-fast markdown parser.
Use docute-cli to initialize the docs folder.
Using npm:
npm i -g docute-cliUsing Yarn:
yarn global add docute-cli
You don't really need docute-cli, it's just a tool for scaffolding out a doc folder and bringing you a dev-server with live reloading support. You can use any similar tool, for example, live-server + yeoman generator, or simply crafted by hand if you like, there's not much work you have to do!
Assume that the folder you want for docs is ./docs:
docute init ./docsNow the ./docs folder is ready, so far we got:
- README.md: Used as content of homepage
- index.html: The html that contains the scripts and styles you need
- .nojekyll: Indicates that this is not a jekyll website, ignore this if you're not deploying to github pages
Then you can preview the docs locally:
docute ./docsOpen http://localhost:8080 and you'll see it in action.
Do you hate node.js or npm? Or just being too lazy to install them? You know you don't need to install docute-cli at all!
What we really need is an index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" />
<title>My Awesome Doc</title>
<!-- the docute client styles -->
<link rel="stylesheet" href="https://unpkg.com/docute/dist/docute.css">
</head>
<body>
<div id="app"></div>
<!-- load the docute client library -->
<script src="https://unpkg.com/docute/dist/docute.js"></script>
<!-- bootstrap your docute app! -->
<script>
docute.init()
</script>
</body>
</html>And that's it!
docute.init accepts an argument for setting configurations:
docute.init({
// ...config goes here
})docute.init({
url: '.' // default
// Use files from another source
url: 'https://cdn-to-markdown-files.com/'
})The URL to your website, eg: http://example.com/docs or /docs, the markdown files will be fetched from this url, when using the default value .:
- When you visit
/it will fetch./README.md - When you visit
/en/guideit will fetch./en/guide.md - When you visit
/es/about/it will fetch./es/about/README.md
README.md in your docs folder will be treated as homepage for your website, but sometimes you may need to serve another file as your homepage. For example you're deploying ./docs as github pages but already have README.md in your repo, why do you have to populate another file at ./docs/README.md, right? Then just tell it which file we should use:
docute.init({
// use a markdown file from url directly
home: 'https://raw.githubusercontent.com/egoist/docute/master/README.md'
})You can set the landing option to true or a custom path or a markdown string:
docute.init({
// or custom path
landing: '_my-landing.html',
// or even markdown file
landing: 'landing.md',
// or inline markdown
landing: '# this is landing page'
})If you enable landing page, the route / will match landing page, and /home will be the homepage of docs.
You cannot use script tag in pages, since dynamically added scripts will not be evaluated by your browser.
The landing option could also be an object:
docute.init({
landing: {
source: 'landing.html'
}
})Same as using string as the value of landing.
docute.init({
landing: {
markdown: '## inline markdown',
// or:
// html: '<h2>inline html</h2>'
}
})You can use inline content, html is similar to markdown here, except that it won't be parsed by marked.
You can even use it with a Vue component:
docute.init({
landing: {
markdown: '## counter\n {{ count }} ',
component: {
data() {
return { count: 0 }
}
}
}
})You can also add more markdown files to display more pages. For example, adding chinese.md to your doc folder so that you got a new page at /#/chinese!
It supports directory too, just try adding a new file at language/chinese.md, then you'll get /#/language/chinese.
Note: file like about/README.md will be mapping to /#/about/, while the /#/about is for about.md.
To disable the sidebar globally, set it to false in config.js:
docute.init({
sidebar: false
})Or disable it for specific page:
---
sidebar: false
---
disable sidebar for this page.There will be a toggle button for switching sidebar on and off, to hide this button:
docute.init({
disableSidebarToggle: true
})The TOC is coming from your markdown files, we parse markdown content and get headings (h2 to h5+) to group a nested TOC.
In sidebar we will show h2 to h4 headings by default, h5+ only will be visible when the main content scrolls there, you can update this by:
docute.init({
// to show h2 to h3 only
tocVisibleDepth: 3
})It's true by default, to disable TOC entirely, set toc to false.
If you don't want to use auto-generated toc, you can specify a custom toc to display on the sidebar:
docute.init({
toc: `
- [Install](/install)
- [Guide](/guide)
- [How to do A](/guide/how-to-do-a)
- [How to do B](/guide/how-to-do-b)
`
})
// or a remote file:
docute.init({
toc: './toc.md'
})To make it eaiser to write, you can get toc content from an HTML element:
<script id="my-toc" type="text/x-markdown">
- [Install](/install)
- [Guide](/guide)
- [How to do A](/guide/how-to-do-a)
- [How to do B](/guide/how-to-do-b)
</script>
<script>
docute.init({
toc: document.getElementById('my-toc').textContent
})
</script>All the value types that are supported in landing option are supported here as well.
Besides, toc could also be a function which accepts $route as the only argument.
Currently custom toc is not supported in front-matter, however you can enable custom toc globally by setting `toc` in `docute.init()`, and set `toc` to `true` in front-matter when you need auto-generated toc for specific page.
You may need a navbar as the entrance for the pages:
docute.init({
nav: [
// homepage
{title: 'Home', path: '/'},
// chinese doc
{title: 'Chinese', path: '/language/chinese'}
]
})
The `path` could also be an external URL, it will work exactly like a normal hyperlink.
Besides this, as you've learned in Pages section, something like /language/chinese will fetch `/language/chinese.md`, if you want to fetch an external file just set the source option like `source: 'https://foo.com/bar.md'`
A path like /language/chinese will make docute fetch /language/chinese.md, you can use source option to fetch another file:
docute.init({
nav: [{
title: 'Chinese',
path: '/language/chinese',
source: '/language/chinese-foo.md'
// or even external file
source: 'https://raw.githubusercontent.com/user/repo/master/file.md'
}]
})You may wonder why there's `home` option when we already have `source` option, that's because `source` option is only available for nav item, while `home` is always available no matter if you add `/` to nav.
If you use absolute path in `source` option, it will fetch files from the root of your domain, which means if your website is `http://example.com/docs`, it will fetch `http://example.com/foo.md` with `source: '/foo.md'`
If you don't want it to fetch external files, use markdown option:
docute.init({
nav: [{
path: '/',
markdown: '# Home'
}]
})Use the fetched content or inline content as the template of a Vue component:
docute.init({
nav: [{
path: '/',
markdown: '## counter\n {{ count }}', // this will be parsed to html first
component: {
data() {
return { count: 0 }
}
}
}]
})docute.init({
// slug for your github repo
repo: 'tj/co',
// twitter username
twitter: 'realDonaldTrump',
// the link to source file of current page
'edit-link': 'https://github.com/egoist/docute/blob/master/docs'
})To fully customize the label, link or use custom svg icons, see below.
The built-in svg icons: github twitter edit menu link search close info, which you can use in the icon attribute in icons option:
docute.init({
icons: [{
icon: 'github',
label: 'Contribute on GitHub',
link: 'https://github.com/owner/repo'
}]
})This example will have the same effect as using repo: 'owner/repo' but with custom label text here.
If you want to use your own SVG, you can set custom icon by providing the id of SVG symbol, SVG symbols is just a simple way to use inline SVG.
First, add it to your HTML file, which is index.html here:
<body>
<div id="app"></div>
<!-- you can add it everywhere outside #app -->
<svg xmlns="http://www.w3.org/2000/svg" style="display:none">
<symbol id="my-icon" viewBox="0 0 22 22">
<!-- all shapes like `<path>` go here -->
</symbol>
<!-- ... other symbols -->
</svg>
</body>Then use it in config.js:
docute.init({
icons: [
{
label: 'Hovered!', // the text for tooltip
svgId: 'my-icon', // the id of symbol
link: 'http://blah.blah'
}
]
})You can also add svgClass property to use CSS to control the style of your icon
docute.init({
icons: [
{
label: 'Hovered!',
svgId: 'my-icon',
svgClass: 'my-icon-class',
link: 'http://blah.blah'
}
]
})/*
To make consistent with default icon hover effect
You can:
*/
.my-icon-class {
fill: #ccc;
}
.my-icon-class:hover {
fill: #333;
}Check out index.html and config.js of this doc to see how we add a custom icon for weibo.com (the last icon in the header).
There're many resources for good free SVG icons, for example: bytesize-icons and simple icons.
You can have multiple sets of icons and use different set for different pages, just set the icons to a plain object:
docute.init({
icons: {
default: [{label: 'hello'}],
chinese: [{label: '你好'}]
}
})Now, every page would use default icons, to use chinese icons just add front-matter in your page:
---
icons: chinese
---
hello world!The item in navbar could also be a dropdown menu:
docute.init({
nav: [
{title: 'Languages', type: 'dropdown', items: [
{title: 'Chinese', path: '/language/chinese'},
{title: 'Japanese', path: '/language/japanese'}
]}
]
})Type: RegExp
To make dropdown menu display the actual title of active page, for example, show Chinese instead of Languages as the dropdown title when user enters relevant page, use matchPath. The target of matchPath is this.$route.path,eg: in https://example.com/en/get-started the target is /en/get-started
docute.init({
nav: [{
title: 'Languages', type: 'dropdown', items: [{
path: '/en',
title: 'English',
// show `English` instead of `Languages` as the dropdown title
// only match `/en` and `/en/xxx` not `/enxxx`
matchPath: /^\/en[\/$]/
}]
}]
})If no macthed item was found, it uses the title of dropdown menu instead.
To have such dropdown menu:
You will need the label and sep helper:
docute.init({
nav: [
{
title: 'Ecosystem', type: 'dropdown', items: [
{type: 'label', title: 'Help'},
// ... items
{type: 'sep'} // separator
// ... other items
]
}
]
})You can have multipage navbar and use different navbar for different pages.
If the nav option in config file is an array, it will be the only navbar across pages, but you can also set it to a plain object to have multiple named navbar:
docute.init({
nav: {
default: [{title: 'Home', path: '/'}],
chinese: [{title: '首页', path: '/chinese'}]
}
})For now all pages will still use the default navbar, but you can switch this by setting front-matter in your markdown file:
---
nav: chinese
---
<!-- this page use the `chinese` navbar -->
你好世界!To display an announcement at the top of doc content:
docute.init({
announcement: 'Welcome to the documentation of XXX!'
})
// Or with type:
docute.init({
announcement: {
type: 'warning', // warning | danger | success | primary
html: 'This doc is out-dated!'
}
})
// Even function
docute.init({
announcement: function (route) {
if (/\/chinese/.test(route.path)) {
return 'Welcome, Chinese users!'
}
return 'Welcome, English users!'
}
})You can also set announcement in front-matter.
docute uses marked to parse markdown code,you can adjust marked's settings by:
docute.init({
marked: {
smartypants: true
// ...
}
})Please refer to the official docs for details about its options.
Set debug to true to enable vue-devtools:
docute.init({
debug: true
})You can use hash or history mode for router:
hash(default): uses the hash portion of the URL (i.e. window.location.hash) to keep your UI in sync with the URLhistory: uses the HTML5 history API (pushState, replaceState and the popstate event) to keep your UI in sync with the URL
hash mode suits all kinds of apps and browsers, especially useful when you can only deploy your app to a static web server like github pages.
To enable history mode, you will need to set a url for your website:
docute.init({
url: docute.isDev ? location.origin : 'http://my-project.com/docs',
routerMode: 'history'
})Since all resources would be fetched from a path relative the url, the default url is . which is good for hash mode but will break in history mode.
In history mode it should be either a full url (starts with http) or an absolute path like /path/to/docs
You can use some CSS to customize the look. Beside the gorgeous default theme now you're looking at, we provide the theme-github.css to make it look more similar to the color scheme that github uses. You can load the CSS after docute.css to apply it:
<link rel="stylesheet" href="https://unpkg.com/docute/dist/theme-github.css" />To build another theme, you can check out https://github.com/egoist/docute/blob/master/src/css/theme-github.css for reference.
The title in browser tab is the title you defined in nav property in config file, this value will also be used in navbar item.
However, you can use front-matter in markdown to override page title:
---
title: Home
---
For example, I want this page to be shown as 'English' in navbar but 'Home' in browser tab.docute uses Prism.js to highlight your code blocks, however only a few languages are supported by default, you can highlight other languages by:
<script src="/path/to/docute.js"></script>
<!-- add your language after the main docute bundle -->
<script src="https://unpkg.com/prismjs/components/prism-python.js"></script>Now the python code will get highlighten!
def fib(n):
a,b = 1,1
for i in range(n-1):
a,b = b,a+b
return a
print fib(5)The built-in languages are:
[ 'markup',
'xml',
'html',
'mathml',
'svg',
'css',
'clike',
'javascript',
'js',
'json',
'bash',
'yaml',
'markdown' ]Visit https://unpkg.com/prismjs/components/ for all available programming languages.
CSS helpers make your docs even more readable.
Show some tips in your doc:
<p class="tip">
This is for beginners and pros, just enjoy!
</p>And you get:
This is for beginners and pros, just enjoy!
Note that you can still use markdown inside the HTML!
Similar to p.tip but it looks more serious:
<p class="warning">
Do not do like this, do it that way please. If you still can't help doing such way, we will call your mom and order some pizza to let you know, you're in trouble!
</p>And you get:
Do not do like this, do it that way please. If you still can't help doing such way, we will call you mom and order some pizza to let you know, you're in trouble!
<p class="danger">
This is really dangerouse, watch out!
</p>And you get:
This is really dangerous, watch out!
If you don't like tips with background color, remove it by adding no-bg class name:
<p class="warning no-bg">
How is it going?
</p>And you get:
How is it going?
<button class="docute-button">Button</button>Button
<button class="docute-button docute-button-mini">Mini Button</button>Mini Button
<button class="docute-button docute-button-primary">Primary Button</button>Primary Button
<button class="docute-button docute-button-success">Success Button</button>Success Button
<button class="docute-button docute-button-danger">Dangerous Button</button>Dangerous Button
<button class="docute-button docute-button-warning">Warning Button</button>Warning Button
Markdown links like [Go](#heading-slug) will navigate you to ?id=heading-slug in current page.
Markdown links like [Go](/page#heaing-slug) will navigate you to /page?id=heading-slug
In hash router mode, the path will automatically be prefixed with /#/ so that you don't need to add it yourself.
Alternatively, you can use HTML attributes directly:
<!-- Navigate to another page -->
<a router-link="/zh-cn/get-started?id=optional-id">
Get Started!
</a>
<!-- Navigate to `?id=hello-world` in current page -->
<a jump-to-id="hello-world">
Hello World
</a>The element tag doesn't have to be a, anything meets your need like button is available here.
You can access following global variables if you need:
docute
docute.version // the version of docute
docute.store // Vuex store instance
docute.router // Vue router instance
docute.init // bootstrap app, you can only call it once
docute.isDev // if you're running docute as `localhost`
Vue // Vue constructorSince a docute website is purely SPA, it's a bit different from using Google Analytics in traditional website, just add following markup to the end of your HTML file (within <body> but after loading docute.js):
<!-- Google Analytics -->
<script>
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
ga('create', 'UA-XXXXX-Y', 'auto');
ga('send', 'pageview');
docute.router.afterEach(function (to) {
ga('set', 'page', to.fullPath);
ga('send', 'pageview');
});
</script>
<script async src='https://www.google-analytics.com/analytics.js'></script>
<!-- End Google Analytics -->
Note that the UA-XXXXX-Y indicates your own track id.
There're three places to populate your docs:
./docsfolder- master branch
- gh-pages branch
Just select it in repo's settings page after pushed files:
Try following nginx conf:
server {
listen 80;
server_name your.domain.com;
location / {
alias /path/to/dir/of/docs;
index index.html;
}
}Or if you want to serve it at sub path like /docs, try:
server {
listen 80;
server_name your.domain.com;
location /docs {
alias /path/to/dir/of/docs;
index index.html;
}
}Yes and No. Yes is because they are both for writing documentation and they have the similar UI, but docute does not require you to generate static html files, and have less configurations while still keeping the most useful features for writing elegant docs.
docute is also built by what I've learned from using gitbook/hexo/jekyll in the past years.
It's not wrong, but we don't always need it that way, sometimes a simple Single Page Application is good enough for our docs while we can get rid of some verbose steps to publish docs. In fact, we're also looking forward to supporting this feature and server-side rendering at some point, I know many SEO guys and girls would like this even if Google already supports retrieving data from SPA website.
Since dynamically added script tags won't be executed by browser, you can use docute-iframe plugin to run specified code blocks in an iframe.
For docs about plugins please head to plugins.

