This is my first post 🎉 please leave a comment on it, and my site and don't be gentle. Cheers!
The purpose
I needed a site where I could publish some posts to learn in public and keep my knowledge in one place. I often find myself googling stuff I used to develop something while I have to do something similar. I want to write about my process and keep it on trzos.dev, but first I need an MVP, therefore the blog.
The stack
I choose, Sapper, Tailwind, Dev.to. Let's delve a bit into each of them.
- Sapper - It's Svelte universal app framework. After I watched Rich Harris talk I thought I'd love to work with it. The concept is great, it offers amazing (and fun) developer experience, and I love to experiment with something new. I chose Sapper over Svelte for better SEO and static site generation.
- Tailwind - It's a utility first CSS framework from Adam Wathan. It looks a bit ugly in the code at first, but it really makes it easier to maintain and it's just amazing how well it works with component-based frameworks. Utilities for animations and transitions coming soon as well. Can't wait!
- Dev.to - I choose this to have a platform to write on, and I like their policies. I guess you already know that they are better than others though, as you're probably a dev.to reader 😅. Bonus points for Markdown editor and API. Feels like a good place for developers 🤓
Setup
First, we need to create an app with Sapper. Fortunately someone prepared a script for us that generates it automatically. Just go to your projects folder and run one of below.
# for Rollup
npx degit "sveltejs/sapper-template#rollup" my-app
# for webpack
npx degit "sveltejs/sapper-template#webpack" my-app
You can choose Rollup or Webpack. I choose Webpack because I'm more familiar with it, but it's totally up to you. They are both good module bundlers.
Next, we need to run the project.
cd my-app
npm install
npm run dev & open http://localhost:3000
You're good if you can see Borat on the main page. I told you Svelte is fun 😄
Next, we would like to add Tailwind. I used this tutorial, and it works well. Just keep in mind that you can use
npx tailwind init
instead of the command that runs a script from /node_modules/
. Does the same thing, it's just easier to type in. PostCSS config file in this example looks for tailwind.js
instead of tailwind.config.js
. Watch out and fix one or the other.
I went with PurgeCSS and I recommend you to do so as well. It saves some kB on the app as it shaves off unused classes. That's brilliant with Tailwind as you can have all generated utility classes and drop unused ones on production 💪🏻
You will know that Tailwind is installed first by the fact that Borat image went left for some reason, and that you can actually use Tailwind classes. I'd recommend to remove the global.css
file from /static
folder and from template.html
. You probably won't need this when you use Tailwind.
The blog
Sapper boilerplate comes with a blog example. In the routes
folder, you will find the blog
directory, which represents your /blog
route. I removed all .js
files there as their purpose is to mock API calls for posts and we will use dev.to
API. You should be left with blog/index.svelte
and blog/[slug].svelte
, which are for the blog feed and each blog post accordingly.
Let's focus on index.svelte
. First we need to call dev.to
API instead of the local mock.
<script context="module">
export function preload({ params, query }) {
return this.fetch(`https://dev.to/api/articles/?username=remotelydev`)
.then(r => r.json())
.then(posts => {
return { posts };
});
}
</script>
Replacing first script tag with one above should do the trick. Notice that I target my publushed posts. Make sure to use you username.
Now on the blog page, you should see a list of my/your posts published on dev.to
. The link is broken though, let's fix that!
Still in blog/index.svelte
update the link in the list to pass id in the query like this
<a rel="prefetch" href="blog/{post.slug}?id={post.id}">
<h2 class="text-black">{post.title}</h2>
</a>
Now clicking the link will also pass the post.id
which is necessary to fetch the exact post. It's not the best solution, but it was first and working one I could think of. Leave a comment with a better idea, and I'll update the post. 👌🏻
Let's go to blog/[slug].svelte
and update the first script tag with
<script context="module">
export async function preload({ params, query }) {
// the `slug` parameter is available because
// this file is called [slug].svelte
// const res = await this.fetch(`blog/${params.slug}.json`);
const res = await this.fetch(`https://dev.to/api/articles/${query.id}`);
const post = await res.json();
if (res.status === 200) {
return { post };
} else {
this.error(res.status, post.message);
}
}
</script>
See how I used the post id
to get proper post? It's needed to get exact your post. Sapper is cool enough to make the call on server side.
All left to do is to use proper content property from the response. For dev.to
API it's post.body_html
instead of post.html
from the boilerplate. And you have your blog with Svelte and Dev.to 🎉 Just add some personal info, styles and write your posts! Cheers! 👋🏻
P.S.: I use Sapper generate functionality. It walks through all your routes and links and generates static site from it. Pretty neat! I like this particularly because you can have a static site if you don't need to keep users logged in, but if you'll ever decide that you want to you can serve the app as usual.
Top comments (0)