200 OK status code
Use Harp’s 200 file to route a client-side app.
Why
If you’re writing a client-side application using a framework like Backbone, Angular, or Ember, you’ll want to do your routing client-side using HTML5 pushState. A 200 fallback file lets Harp respond with a 200 OK status (and your app shell) for any unmatched URL — leaving the client-side router to take over from there.
Usage
Add a 200.html file in your served directory. (200.ejs, 200.md, or 200.jade work too — they’ll compile to HTML.) When a request doesn’t match any other file, Harp returns the contents of the 200.* file with a 200 OK status code instead of falling through to a 404.
Example
Given the following directory structure:
mysite/
|- 200.ejs
|- app.js
|- framework.js
`- main.scss
The 200.ejs file is served when nothing else matches the request, but before falling through to a 404. Your client-side router can then pick up the URL and render the right view.
This works alongside static pages. If you had a client-side app but wanted your blog to remain static, your project might look like this:
mysite/
|- _layout.ejs
|- 200.ejs
|- css/
| `- main.scss
|- js/
| |- app.js
| `- framework.js
`- blog/
|- _data.json
|- index.ejs
|- my-post-1.md
`- my-post-2.md
Visiting /blog returns the static blog. Visiting any URL that doesn’t match a real file (/dashboard/users/42, say) is served the 200.ejs fallback so your client-side router can handle it.
Cascading 200 files
200.* files cascade up the directory tree. When a request misses, Harp walks up from the request path, and at each directory level checks for a 200.* first and then a 404.*. The first match wins.
This means each section of your site can have its own client-side fallback:
mysite/
|- 200.ejs <-- top-level fallback
|- index.ejs
|- admin/
| |- 200.ejs <-- only for unmatched /admin/* URLs
| `- index.ejs
`- blog/
|- index.ejs
`- my-post.md
A request like /admin/users/42 matches admin/200.ejs (deeper directory wins). A request like /missing-page walks up and is served the top-level 200.ejs. Requests under /blog/ that don’t match a real file also walk up to the top-level 200.ejs, since blog/ has no fallback of its own.
A
200.*and a404.*in the same directory: the200.*wins. Use one or the other per directory based on the behavior you want there.
Compile output
When you run harp <source> <build>, 200.* files are emitted as static 200.html in the corresponding output directory. To preserve the fallback behavior on a static host, configure your host to serve 200.html as the catch-all — most static hosts (Netlify, Vercel, Cloudflare Pages, S3 with routing rules) support this directly.
Client-side routers
There are lots of client-side routers and frameworks to play with: