Headless WordPress with Sapper (Part 1)
Tags: javascript, sapper, svelte, wordpress
Published: 2020-08-09 14:26:44

####  #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](https://svelte.dev/blog/sapper-towards-the-ideal-web-app-framework)

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.

{%youtube lnu6OdK0jS0%}
#### #2 WordPress setup

Here you need to setup an instance on your own on your server you can follow [this](https://wordpress.org/support/article/how-to-install-wordpress/) 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](https://developer.wordpress.org/rest-api/using-the-rest-api/) 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

```
└───routes
│   │   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` 



```js
	export function preload({ params, query }) {
		return this.fetch(`blog.json`).then(r => r.json()).then(posts => {
			return { posts };
		});
	}
```
```html
<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

![WP-Sapper](https://dev-to-uploads.s3.amazonaws.com/i/t8avbsmupi64e1zsljml.jpg)

Now this is a great success 🎉🎉 Similarly we should also modify the `[slug].svelte`

```js

	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](https://www.npmjs.com/package/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](https://pages.github.com/).