DEV Community

Cover image for Headless WordPress with Sapper (Part 1)
Shriji
Shriji

Posted on • Updated on

Headless WordPress with Sapper (Part 1)

#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
Enter fullscreen mode Exit fullscreen mode
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

└───routes
β”‚   β”‚   index.svelte
β”‚   β”‚   about.svelte
β”‚   β”‚   _layout.svelte
|   |   _error.svlete
β”‚   └───blog
β”‚       β”‚   [slug].svelte <----
β”‚       β”‚   index.svelte
β”‚       β”‚   ...
Enter fullscreen mode Exit fullscreen mode

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 };
        });
    }
Enter fullscreen mode Exit fullscreen mode
<li><a rel='prefetch' href='blog/{post.slug}'>{post.title}</a></li>
Enter fullscreen mode Exit fullscreen mode

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

WP-Sapper

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);
        }
    }

Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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.

Latest comments (9)

Collapse
 
anilbhattaraitoronto profile image
Anil Bhattarai

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

Collapse
 
shriji profile image
Shriji

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.

Collapse
 
anilbhattaraitoronto profile image
Anil Bhattarai

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.

Thread Thread
 
shriji profile image
Shriji

Thanks, I think permalinks will create unique slugs.

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

Thread Thread
 
anilbhattaraitoronto profile image
Anil Bhattarai

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

Thread Thread
 
shriji profile image
Shriji

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

Thread Thread
 
anilbhattaraitoronto profile image
Anil Bhattarai

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.

Thread Thread
 
anilbhattaraitoronto profile image
Anil Bhattarai

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

Thread Thread
 
shriji profile image
Shriji

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...