Sapper setup
Setting up Sapper is very easy to install for more details check here. I personally prefer 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
Once you have opened the project in your editor you will notice a confusing directory structure that may look daunting at first but it is pretty straight forward when it comes to producing your SSG part of Sapper.
└───routes
│ │ index.svelte
│ │ about.svelte
│ │ _layout.svelte
| | _error.svlete
│ └───blog
│ │ [slug].svelte
│ │ index.svelte
│ │ [slug].json.js
│ │ _posts.js
│ │ index.json.js
In Sapper, any file with _
underscore at the beginning is a hidden/private file. Our logic to obtain blog posts via API from Trello happens in the _posts.js
file which generates the right JSON files for the blog posts. [slug].svelte
and index.svelte
contains template responsible for list of posts and the post itself. [slug].json.js
and index.json.js
exports the JSON it is possible without these files and yet has SSG done but it is a major hit on the performance and is very much noticeable with my series on headless WordPress and Sapper.
Snippet for _posts.js
where we export a JSON object that has data for the blog post that could be populated on index.svelte
and [slug].svelte
//_posts.js
import fetch from "node-fetch";
let data = {};
let url = `https://api.trello.com/1/lists/5f538d3a842e0a3b6ce9f259/cards?key={key}&token={token}`; //this is from your previous post
let trello = async function getPosts() {
const res = await fetch(url);
data = await res.json();
return (data = data.map((e) => {
const months = ["jan", "feb", "mar","apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"];
let posted_date = new Date(e.dateLastActivity)
let formatted_date = `${posted_date.getDate()} ${months[posted_date.getMonth()]} ${posted_date.getFullYear()}`
let tags = e.labels.map(e=>{
return {
name:e.name,
color:e.color
}
})
return { title: e.name, slug: e.name.toLowerCase().replace(/[^\w ]+/g,'').replace(/ +/g,'-'), desc: e.desc, image:e.cover.scaled,time:formatted_date,tags };
}));
};
export default trello;
After a slight modification to index.json.js
and [slug].json.js
we can automatically get Trello items as blog posts.
//index.json.js
import trello from "./_posts.js";
export async function get(req, res) {
res.writeHead(200, {
"Content-Type": "application/json",
});
let data = await trello();
let posts = data;
posts = posts.map((post) => {
return {
title: post.title,
slug: post.slug,
time: post.time,
tags: post.tags
};
});
res.end(JSON.stringify(posts));
}
//[slug].json.js
import trello from './_posts.js';
const lookup = new Map();
export async function get(req, res, next) {
// the `slug` parameter is available because
// this file is called [slug].json.js
const { slug } = req.params;
let data = await trello()
data.forEach(e => {
lookup.set(e.slug, JSON.stringify(e));
});
if (lookup.has(slug)) {
res.writeHead(200, {
'Content-Type': 'application/json'
});
res.end(lookup.get(slug));
} else {
res.writeHead(404, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify({
message: `Not found`
}));
}
}
Top comments (0)