Reveal.js is awesome. It generates slick presentations, it’s packed with features and plugins, and it’s got one hell of a good in-browser editor. But what if you’re running it on your own server? Editing slides through text is fine (and fun), but each slide requires a separate instance of Node running to serve it…right?


There’s a quick and simple workaround that lets you serve up any number of presentations with one node process and access them by directory???—???no more going to a .html page to view the slideshow. [Disclaimer: this is a really small and stupid point, but I’m really picky about this stuff so I made sure I could do it. Any time I go to a page with an extension I am automatically slightly less comfortable than with a directory link.]

Step 1: Grunt Work

(Holy crap I am proud of that pun)

First, go ahead and clone the Reveal.js repository as with any presentation. Create a folder in the repository; this will be the parent directory of all your slideshows (I named mine decks). Now open up Gruntfile.js in the root of the repository and find this section:

options: {
livereload: true
js: {
files: [ ‘Gruntfile.js’, ‘js/reveal.js’ ],
tasks: ‘js’
theme: {
files: [ ‘css/theme/source/*.scss’, ‘css/theme/template/*.scss’ ],
tasks: ‘css-themes’
css: {
files: [ ‘css/reveal.scss’ ],
tasks: ‘css-core’
html: {
files: [ ‘index.html’ ]

This section tells Grunt what to watch for changes. Upon a modification of any watched file, it re-serves the changed files. We want it to look at more than just index.html in the current directory; we want it to watch all of our separated presentations. Thus, let’s change the code inside the html section slightly:

    html: {
files: [ 'index.html', 'decks/*/index.html' ]

This will watch all index.html files in a subdirectory of decks???—???exactly what we want.

Step 2: Higher Management

(Not as good, but I’ll go with it)

Because presentation data is going to be in a slightly different spot, we’re going to have to tweak where it looks for CSS, JS, and plugins. Go back to your decks folder. Each presentation will have its own separate folder???—???/decks/pres1/, /decks/pres2/, and so on. I suggest you copy the original index.html that comes with Reveal.js into this new folder, trim out the slides, and then use it as a template once we make some changes. We’re essentially just preprending ../../ to the start of a lot of paths, which tells the presentations to look for resources in the repository’s root directory rather than the presentation’s immediate directory. We’ll do this for all hrefs or srcs starting with /lib, /plugin, /js, or /css. For instance:

<link rel="stylesheet" href="lib/css/zenburn.css">

now becomes

<link rel="stylesheet" href="../../lib/css/zenburn.css">

And boom! Bob’s your uncle, you’re done. If you actually have an uncle named Bob, let me know.

Incidentally, organizing each presentation like this has an added side effect in terms of organization???—???each presentation and its content, like images, videos, and other resources???—???is a reasonably self-contained unit stored in its own folder.

Step 3: Bonus Tips!

Oh man oh man oh maaaaaan. There’s more useful info in this post? Wow.

If you’re like me, you want to leave presentations running on your server, but you might not want to stop and restart Grunt every time you log out and back in, or worse, kill and restart it if your remote connection drops. Enter screen, one of my favorite unix tools and an all-around useful utility. Screen is exactly what it says???—???it sets up a virtual screen that you can attach to and detach from in any terminal window. To start one, just type screen. If you want to detach from it, press Ctrl+A and then D; this will pop you out of the virtual screen and back to your regular prompt. To rejoin it, screen -r is the command you want; if there’s only one screen running in the background it’ll drop you in, and if there are more it will list them for you.

To make things simpler, you can give a screen a name with the -S (that’s a capital S) flag; instead of having to remember a process ID you can use screen -r <name> to rejoin it.

And to make things better, you can run a screen with a command in mind! There’s no flag for this one, it’s just the command. In our case, then, the command we’re looking to run is

screen -d -m -S <desired screen name> grunt serve

Woah hang on! What are those d and m flags? Those tell the screen to start but in the background. If you run this at boot, when your server starts you’ll have a screen dedicated to your presentation log ready and waiting for you to drop in. I’m not going to suggest a way to run it at boot, because if I do, no matter the method I know I might get angry sysadmins yelling at me. So do some exploring and look it up!

I hope this is somewhat helpful to people; when searching for info on multiple presentations, I mostly just found results discussing multiplexing presentations, or letting others view pages where the presentations are being controlled by a master presenter.