Cover image for Headless WordPress with Sapper (Part 1)

Headless WordPress with Sapper (Part 1)

shriji profile image Shriji Updated on ・3 min read

#1 What is Sapper?

Sapper is the companion framework of svelte, like how Next/Nuxt is for React/Vue. You have the benefits of svelte and all the SEO powerhouse and Server Side Rendering. You can read more about sapper here

Since the release of WordPress 4.7+ it comes with REST API comes out of the box. You could consume the API and JAMStack it πŸ˜‰, Essentially it makes you a powerful website having a WordPress as backend where you feed data.

#2 WordPress setup

Here you need to setup an instance on your own on your server you can follow this or countless youtube tutorials.

Next immediate steps that ensure your API works well.

https://your-domain/wp-json/wp/v2/posts is the endpoint for getting your posts as JSON

You can also pass queries like slug=post-name this may not work so make sure in your WordPress dashboard permalink is set to %postname%.

The settings can be found here https://your-domain/wp-admin/options-permalink.php

The API Documentation isn't that great at the moment but most of the issues can be resolved with a quick search on google.

#3 Installing Sapper

It is as easy as installing any other package and Sapper also comes with a choice of the bundler, I personally like rollup.

# for Rollup
npx degit "sveltejs/sapper-template#rollup" my-app
# for webpack
npx degit "sveltejs/sapper-template#webpack" my-app
cd my-app

npm install
npm run dev & open http://localhost:3000
Paste from https://sapper.svelte.dev/

#4 The beauty of [slug] in Sapper

Slugs much like how WordPress slugs are some way to tell Sapper that it is the route and to some extent you could also pass some params other than slug and in the base template of sapper you will find them here

β”‚   β”‚   index.svelte
β”‚   β”‚   about.svelte
β”‚   β”‚   _layout.svelte
|   |   _error.svlete
β”‚   └───blog
β”‚       β”‚   [slug].svelte <----
β”‚       β”‚   index.svelte
β”‚       β”‚   ...

Now some housekeeping is required and make it work with API from WordPress, we only require [slug].svlete and index.svelte

    export function preload({ params, query }) {
        return this.fetch(`blog.json`).then(r => r.json()).then(posts => {
            return { posts };
<li><a rel='prefetch' href='blog/{post.slug}'>{post.title}</a></li>

replace blog.json with the WordPress API url https://your-domain/wp-json/wp/v2/posts and {post.title} to {post.title.rendered} the API has the title of the post under rendered


Now this is a great success πŸŽ‰πŸŽ‰ Similarly we should also modify the [slug].svelte

    export async function preload({ params, query }) {
        const res = await this.fetch(`blog/${params.slug}.json`);
        const data = await res.json();
        if (res.status === 200) {
            return { post: data };
        } else {
            this.error(res.status, data.message);

repalce blog/${params.slug}.json with https://your-domain/wp-json/wp/v2/posts/wp/v2/posts?_embed&slug=${params.slug} and {@html post.html} to {@html comment.content.rendered}

_embed query will get you featured image and comments on the post. The next part in the series will have a tutorial on how to post comments via API.

Now it is complete, with some extra css sugar you can make a beautiful and powerful custom frontend for your WordPress site.

#5 Adding API endpoints as env variables

You can add a .env file to hold all the API endpoints and avoid typos and wrong URLs for this we need sapper-environment.

The configuration looks like this.

SAPPER_APP_API_URL = https://YOUR-DOMAIN/wp-json/wp/v2
SAPPER_APP_API_MENU = https://YOUR-DOMAIN/wp-json/wp/v2/menus/v1

And you can run the npm run export and you would get a full static site generated with respective routes and you serve with nginx/apache or even gh-pages.

Posted on by:

shriji profile



Co-Founder @anoram. High Performance JavaScript Apps. I created https://vadivelu.anoram.com/ and https://biriyani.anoram.com/ API.


markdown guide

The querying of api endpoints for a single post does not seem to be possible, by the way.


wp-json/wp/v2/posts gets you all the posts wp-json/wp/v2/posts?slug=hello-world will give you a particular post also please check for the permalink structure on your WordPress.


Thank you for your reply. I have not tried the permalink with post-name yet, but i am hesitant to use that because there might be posts with same title which might end up creating same post-names and, therefore, maybe conflict with querying. Not sure. I will soon try things out and see how they go.

Thanks, I think permalinks will create unique slugs.

Pls try and let me know. I am glad you find this post helpful.

I could get the request on the browser but not through the sapper page.

That's odd, what seems to be the error?

I saw that the json that I received was an array, not a single object. Therefore, I did iterate for arr[0] to get that single object.

In the [slug] page I did this: return { post: data[0] };

Yes that is right, I have covered it in the next post there are 5 parts right now.

Also I have pushed my repo github.com/peopledrivemecrazy/Sapp...