DEV Community

Shriji
Shriji Subscriber

Posted on

Trello + Sapper JAMstack (Part 3)

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

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

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

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)); } 
Enter fullscreen mode Exit fullscreen mode
//[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` })); } } 
Enter fullscreen mode Exit fullscreen mode

Top comments (0)