# Docsify: Self-Hosted Setup A complete guide to self-hosting Docsify with no external CDN dependencies. We follow the [manual creation](https://docsify.js.org/#/quickstart?id=manual-initialization) but download the JavaScript and CSS files locally so we don't have to worry if the domain cdn.jsdelivr.net get seized (who knows what's going to happen in the future). The result is just static files, so it runs on any web server — Apache, nginx, Caddy, or similar. --- ## Quick Start If you just want a working site, run the bundled script from your document root. It performs every step in this guide automatically: it downloads and version-pins all assets, writes `index.html`, creates starter content, and generates a SHA-256 checksum manifest. ```bash cd /path/to/your/docroot bash /path/to/scripts/setup.sh ``` Re-running is safe: it refreshes the vendored assets and regenerates `index.html`, but never overwrites your Markdown files (`README.md`, `_sidebar.md`, or any pages you have added). Everything below explains what the script does and how to perform each step by hand. --- ## Prerequisites - Any static web server (Apache, nginx, Caddy, or similar) - `curl` (for downloading assets) --- ## Directory Structure The final layout this guide produces, relative to your document root: ``` ./ ├── index.html ← Docsify entry point ├── README.md ← Homepage content ├── _sidebar.md ← Sidebar navigation ├── getting-started.md ← Example page └── assets/ ├── SHA256SUMS ← SHA-256 of every downloaded asset ├── js/ │ ├── docsify.min.js │ ├── search.min.js │ ├── docsify-copy-code.min.js │ ├── docsify-katex.js │ ├── prism-bash.min.js │ ├── prism-yaml.min.js │ ├── prism-python.min.js │ ├── prism-r.min.js │ ├── docsify-plugin-flexible-alerts.min.js │ ├── docsify-tabs.min.js │ ├── docsify-pagination.min.js │ ├── medium-zoom.min.js │ ├── docsify-sidebar-collapse.min.js │ ├── mermaid.min.js │ └── docsify-mermaid.js └── css/ ├── vue.css ├── katex.min.css ├── medium-zoom.css ├── sidebar.min.css └── fonts/ └── KaTeX_*.woff2 (20 KaTeX font files) ``` All commands in this guide assume you have already `cd`'d into your document root. --- ## Step 1: Create the Directory Structure ```bash mkdir -p assets/js mkdir -p assets/css ``` --- ## Step 2: Download Docsify Assets All files are downloaded from jsDelivr once and served locally thereafter. See all [docsify CDN files](https://cdn.jsdelivr.net/npm/docsify@4.13.1/lib/) on jsDelivr. ```bash # Docsify core curl -L "https://cdn.jsdelivr.net/npm/docsify@4.13.1/lib/docsify.min.js" \ -o assets/js/docsify.min.js # Search plugin curl -L "https://cdn.jsdelivr.net/npm/docsify@4.13.1/lib/plugins/search.min.js" \ -o assets/js/search.min.js # Theme (Vue — clean, light) curl -L "https://cdn.jsdelivr.net/npm/docsify@4.13.1/themes/vue.css" \ -o assets/css/vue.css ``` ### Alternative Themes Replace `vue.css` in the command above with any of the following if preferred; see all [themes](https://cdn.jsdelivr.net/npm/docsify@4.13.1/lib/themes/). * buble.css * dark.css * dolphin.css * pure.css * vue.css ### Syntax Highlighting (Prism) Docsify **bundles Prism** and highlights a handful of languages out of the box — `markup`/HTML, `css`, `clike`, and `javascript`. For any other language, download its Prism component and load it **after** `docsify.min.js` (see Step 3) so it attaches to Docsify's bundled Prism. > **Do not download `prism-core.min.js`.** A standalone Prism core loaded after Docsify > replaces Docsify's own Prism on the page; the language components then attach to the > wrong instance and silently fail to highlight. You only need the language files below. This guide adds bash, yaml, python, and r: ```bash curl -L "https://cdn.jsdelivr.net/npm/prismjs@1.30.0/components/prism-bash.min.js" \ -o assets/js/prism-bash.min.js curl -L "https://cdn.jsdelivr.net/npm/prismjs@1.30.0/components/prism-yaml.min.js" \ -o assets/js/prism-yaml.min.js curl -L "https://cdn.jsdelivr.net/npm/prismjs@1.30.0/components/prism-python.min.js" \ -o assets/js/prism-python.min.js curl -L "https://cdn.jsdelivr.net/npm/prismjs@1.30.0/components/prism-r.min.js" \ -o assets/js/prism-r.min.js ``` To highlight more languages, download additional `prism-.min.js` files (browse the [Prism components](https://cdn.jsdelivr.net/npm/prismjs@1.30.0/components/)) and add a matching ` ``` > **Note:** Docsify uses hash-based routing by default, producing URLs like > `/docs/#/page-name`. This requires no web-server configuration whatsoever. --- ## Step 4: Create Boilerplate Content ### Homepage — `README.md` Docsify uses `README.md` in each directory as its index page, just like GitHub. Create `README.md`: ```markdown # Welcome This is the home page of your documentation site. Edit `README.md` to replace this content. ## Quick Links - [Getting Started](getting-started.md) ``` ### Sidebar — `_sidebar.md` The sidebar lists your pages and their navigation structure. Create `_sidebar.md`: ```markdown - [Home](/) - [Getting Started](getting-started.md) ``` Add a new `- [Title](filename.md)` entry here each time you create a new page. ### Example Page — `getting-started.md` Create `getting-started.md`: ```markdown # Getting Started This is an example page. Replace this content with your own documentation. ## Section One Write your content here using standard Markdown. ## Section Two Docsify will automatically generate sidebar anchors for H2 headings when `subMaxLevel: 2` is set in `index.html`. ``` --- ## Step 5: Set File Permissions Since you are creating these files yourself, you already own them. Just ensure they are readable by your web server's user (e.g. `www-data`, `nginx`, or `caddy`): ```bash find . -path './.*' -prune -o -type f -exec chmod 644 {} \; find . -path './.*' -prune -o -type d -exec chmod 755 {} \; ``` The `-path './.*' -prune` clause skips dotfiles and dotdirectories, so if your document root is a Git repository these commands leave its `.git/` permissions untouched. --- ## Serving the Site Docsify is just static files, so **any** web server works — Apache, nginx, Caddy, or even `python3 -m http.server` for a quick local preview. **No server configuration is required:** Docsify's default hash-based routing (`/#/page-name`) means the browser never sends the route to the server, so every request is for a file that exists on disk (`index.html`, a `.md` file, or an asset). There are no rewrite rules to set up — just point the document root at this directory. **Apache** — drop the files in the document root; nothing else needed. **nginx** ```nginx server { listen 80; server_name docs.example.com; root /var/www/docs; location / { try_files $uri $uri/ =404; } } ``` **Caddy** (also provisions HTTPS automatically) ```caddy docs.example.com { root * /var/www/docs file_server } ``` **Local preview** — run `python3 -m http.server` in this directory and open `http://localhost:8000/`. > **Clean URLs (optional):** the only time server config matters is if you switch Docsify > to history-mode routing (`routerMode: 'history'`) to drop the `#` from URLs. Then you > need a fallback so unknown paths return `index.html` — Apache `mod_rewrite`, nginx > `try_files $uri /index.html;`, or Caddy `try_files {path} /index.html`. With the default > hash routing used in this guide, you need none of it. --- ## Verify the Setup After completing the steps above, confirm the file layout looks correct: ```bash # The 20 KaTeX font files are summarised rather than listed individually find . -not -path '*/\.*' -not -path './assets/css/fonts*' | sort echo "./assets/css/fonts/ ($(ls -1 assets/css/fonts | wc -l) KaTeX woff2 files)" ``` Expected output: ``` . ./README.md ./_sidebar.md ./assets ./assets/SHA256SUMS ./assets/css ./assets/css/katex.min.css ./assets/css/medium-zoom.css ./assets/css/sidebar.min.css ./assets/css/vue.css ./assets/js ./assets/js/docsify-copy-code.min.js ./assets/js/docsify-katex.js ./assets/js/docsify-mermaid.js ./assets/js/docsify-pagination.min.js ./assets/js/docsify-plugin-flexible-alerts.min.js ./assets/js/docsify-sidebar-collapse.min.js ./assets/js/docsify-tabs.min.js ./assets/js/docsify.min.js ./assets/js/medium-zoom.min.js ./assets/js/mermaid.min.js ./assets/js/prism-bash.min.js ./assets/js/prism-python.min.js ./assets/js/prism-r.min.js ./assets/js/prism-yaml.min.js ./assets/js/search.min.js ./getting-started.md ./index.html ./assets/css/fonts/ (20 KaTeX woff2 files) ``` Then open `http://your-server/docs/` in a browser. You should see the rendered homepage with a sidebar and search bar — no external requests are made. --- ## Adding New Pages 1. Create a `.md` file in the docs directory (or a subdirectory). 2. Add a corresponding entry to `_sidebar.md`. Example for a new page `reference.md`: ```markdown - [Home](/) - [Getting Started](getting-started.md) - [Reference](reference.md) ``` For subdirectories, nest entries with indentation: ```markdown - [Home](/) - [Getting Started](getting-started.md) - **Advanced** - [Configuration](advanced/configuration.md) - [Deployment](advanced/deployment.md) ``` --- ## Reproducibility & Resilience Self-hosting protects your **live** site if jsDelivr ever disappears. To also protect your ability to **rebuild** it, do two things: 1. **Pin and vendor.** Every asset version is pinned, and the downloaded files are plain static assets. Commit the entire `assets/` directory to your repository. You can then redeploy — or rebuild on a fresh machine with no network access — without depending on jsDelivr at all. 2. **Verify integrity.** `scripts/setup.sh` writes `assets/SHA256SUMS`, a SHA-256 checksum of every downloaded file. Commit it alongside `assets/`, then check the assets at any time (after a server move, or to detect corruption or tampering): ```bash (cd assets && sha256sum -c SHA256SUMS) ``` Every file should report `OK`. After re-running `setup.sh` to upgrade, `git diff` on `SHA256SUMS` shows exactly which assets changed. --- ## Upgrading Docsify Since files are self-hosted, upgrades are manual. Re-run the `curl` commands from Step 2 with a specific version to update: ```bash # Pin to a specific version (replace 4.13.1 with the target version) curl -L "https://cdn.jsdelivr.net/npm/docsify@4.13.1/lib/docsify.min.js" \ -o assets/js/docsify.min.js curl -L "https://cdn.jsdelivr.net/npm/docsify@4.13.1/lib/plugins/search.min.js" \ -o assets/js/search.min.js curl -L "https://cdn.jsdelivr.net/npm/docsify@4.13.1/themes/vue.css" \ -o assets/css/vue.css ``` Every asset version is pinned — in the Step 2 commands above and in the variables at the top of `scripts/setup.sh`. The Prism components, copy-code, Mermaid, the UX plugins, and the math plugin (`docsify-katex@1.4.4` with a matching `katex` stylesheet **and** fonts) are versioned independently of Docsify, so upgrade each by changing its version number and re-downloading. Afterwards regenerate `assets/SHA256SUMS` — re-running `scripts/setup.sh` does this — and re-verify. Check the [Docsify releases page](https://github.com/docsifyjs/docsify/releases) for the latest version number before upgrading. --- ## License Copyright (c) 2026 Dave Tang. This work, including the documentation in this repository and the `scripts/setup.sh` helper, is licensed under the [Creative Commons Attribution 4.0 International License (CC BY 4.0)](https://creativecommons.org/licenses/by/4.0/). You are free to share and adapt the material for any purpose, even commercially, provided you give appropriate credit. See [`LICENSE`](LICENSE) for the full legal text. The third-party assets that `scripts/setup.sh` downloads (Docsify, Prism, KaTeX, Mermaid, and the plugins) are each distributed under their own licenses by their respective authors; this license covers only the contents of this repository.