Self‑Hosting Slidev Presentations: From Markdown to Nginx in Minutes
Share this article
The Rise of Code‑First Presentations
In the developer community, the friction of crafting slide decks in a GUI has long been a pain point—manually aligning elements, hunting colors, and juggling file formats. Slidev flips that paradigm by letting authors write decks in Markdown, sprinkle Tailwind classes for styling, and embed HTML for media. The result is a declarative, version‑controlled slide deck that can be built into static files with Vite.
Why Static Hosting Matters
Static assets are fast, cacheable, and free of server‑side runtime overhead. For a presentation that may be shared with dozens of collaborators or embedded in a blog, serving a pre‑built dist/ folder from Nginx eliminates the need for Node or any runtime, reducing attack surface and simplifying deployment. It also dovetails nicely with modern CI/CD pipelines that can push updates to a CDN or a VPS automatically.
Building the Deck
The core of the process is a single Vite command:
npx slidev build
For a deck that should live under a sub‑path (e.g., https://slides.example.com/chrome-ai-apis/), the --base flag adjusts the internal routing:
npx slidev build --base /chrome-ai-apis/
After the build, the dist/ directory contains a self‑contained index.html and all assets.
Transferring Assets to Your Server
If you generate the files locally, rsync is a reliable way to sync the dist/ folder to a VPS:
rsync -avz --delete dist/ user@server-ip:/var/www/slides/chrome-ai-apis/
If the build runs on the server (e.g., via a GitHub Actions job), the transfer step can be omitted.
Configuring Nginx
A minimal Nginx configuration serves the static files and handles deep‑linking:
server {
listen 80;
server_name slides.example.com;
root /var/www/slides;
index index.html;
location ~ ^/([^/]+)/ {
try_files $uri $uri/ /$1/index.html;
}
}
The regex ensures that a request to /chrome-ai-apis/ resolves to chrome-ai-apis/index.html, preserving the slide navigation. After adding the file to /etc/nginx/sites-available/ and linking it to /etc/nginx/sites-enabled/, validate and reload:
sudo nginx -t
sudo systemctl reload nginx
Optional Enhancements
- HTTPS – Use Cert‑bot to obtain a Let’s Encrypt certificate and add
ssl_certificatedirectives. - CI/CD – A GitHub Actions workflow can run
slidev build, push thedist/contents to the VPS via SSH, and reload Nginx, making updates atomic. - Multiple Decks – Place each deck in its own sub‑folder under
/var/www/slides/and link to them from a simpleindex.htmlthat lists all available presentations.
Common Pitfalls
| Issue | Likely Cause | Fix |
|---|---|---|
Permission errors when copying to /var/www |
Non‑root user lacks write access | Copy to a temp directory, then sudo mv into /var/www or adjust ownership with chown -R www-data:www-data |
| 403 on deck URL | Nginx lacks read permissions | chmod -R o+r /var/www/slides and chmod -R o+X /var/www/slides |
| 500 after deep‑link | Regex mis‑configured | Verify the location block and try_files syntax |
The Bigger Picture
Static hosting of slide decks exemplifies a broader trend: turning content into code, version‑controlling it, and serving it without a runtime. This approach scales from a single talk to a portfolio of talks, each deployable through the same pipeline. It also aligns with modern web practices—leveraging CDNs, caching, and zero‑downtime deployments—while keeping the developer’s workflow lightweight.
Takeaway
Slidev’s Markdown‑first model, coupled with Vite’s static build and Nginx’s efficient serving, delivers a frictionless path from authoring to presentation. By automating the build and deploy steps, teams can focus on content rather than infrastructure, and the resulting static sites are fast, secure, and easy to share.