Introducing Climate SvelteKit Blog StarterΒ #
This SvelteKit Blog starter is based on the existing Climate Gatsby MDX blog starter. Apart from
being built for SvelteKit instead of Gatsby, the other big (related) difference is that it
supports blog posts written in markdown files containing Svelte code (MDsvex), while the Gatsby
version supported MDX (JSX in markdown). Markdown support for blog authoring is quite a handy
feature. There is a shorthand notation which helps you get your thoughts down quicker compared to
more formal HTML. As an example, for a heading in HTML you write <h1>My heading</h1>
, while in Markdown you write # My heading
. There are similar
shorter equivalents for writing lists, adding links, pictures and so on . All in all, it means you spend less time tracking a missing close tag and can focus on the task
at hand. On top, MDsveX makes customizing blog posts a lot easier.
About SvelteKitΒ #
If you are completely new to SvelteKit, it might be worth skimming through my recent post on Getting Started with SvelteKit, which will give you a head-start. That said, I have built the starter to help you get up to speed quicker if you are still discovering SvelteKit. In this post, I outline some key features. If you're more of a hands-on person, just crack open the SvelteKit Blog Starter repo and start playing!
In this post, rather than go through how I built the starter, to help get you going quicker with SvelteKit, I'll run through the most important parts of configuration. As it's based on the Gatsby equivalent, I can also point out some differences. My hope is that you can hit the ground running with help from the starter. We will start looking at what's inside the repo and where you put your own blog posts. Finally, we'll end up with a comparison of Gatsby and SvelteKit, with a look at Server Side generation vs. Static Site Generation thrown in on the journey. If that sounds good to you, let's crack on! If you would find a post on building something like this from scratch useful, do let me know.
π Quick StartΒ #
To get going you will clone the repo, install and spin up a dev server:
You can run pnpm install
instead of npm install
if you have pnpm set up.
π§ Whatβs Inside?Β #
src
Β #
-
hooks.server.js
we define Content Security Policy (CSP) and other HTTP security headers in here. More on this later.
src/lib/components
Β #
-
src/lib/components
these are the components we use in pages.
src/lib
Β #
-
src/lib/config/website.js
for convenience we define properties for the site here such as the site title, contact email addresses and social media accounts. Some properties feed from environment variables. See the earlier post on getting started with SvelteKit for more on environment variables in SvelteKit.
-
src/lib/styles
does what you expect! We use SCSS for styling and source self-hosted fonts in the layouts (we'll see this further down the post).
src/lib/utilities
Β #
-
src/utilities/blog.js
this file contains some code for helping us transform the markdown in blog posts to Svelte. As well as that, they help extract fields in the front matter (this is the metadata we include at the top of the blog postindex.md
files).
src/routes
Β #
-
src/routes/[slug]
this folder contains templates for Svelte pages and backend logic for blog posts.
I mention most of the other files in the Getting Started with SvelteKit blog post, but let me know if I have missed anything which needs more explanation. Next let's look at a blog post file.
π Blog PostsΒ #
Below is a fragment from one of the sample blog posts. The first section is the front matter,
mentioned earlier. For now the SEO content is bare-bones, but in an upcoming post, I will run
through generating SEO metadata for OpenGraph, Twitter and SchemaOrg. In those posts, we will make
more use of post front matter to ensure we include data tailored for each post in the page's
metadata. This has a number of important uses from, having nice pictures show up when your page is
shared on Twitter, Telegram or other apps to helping search engines understand what the page is
about. The latter is needed to improve your SEO ranking. For now, the most critical use is
ensuring we get the right banner image to appear, with expected alt text for each post. If you are
as keen on SEO as I am, you should read my post on SvelteKit SEO. As you might expect, the dates from front matter are used to sort posts in the BlogRoll
component.
π BlogPostSummary ComponentΒ #
Speaking of the blog roll, BlogRoll is used to generate it. We generate one of these components for each blog post. I thought this would be an interesting component to look at to compare Svelte and React code. We want the user to be taken to the blog post when they click anywhere inside the component. So we want it to behave like a link. We also want to include the title and other information as links to the post. Later we might add links to similarly tagged posts within the component.
That's a lot of links! Semantically, you should not have an anchor tag enclosed in another anchor tag. This is what we would have is we used anchors for all the links mentioned just then. Instead, I engineered the component to have the look, feel, and behaviour expected by the user as well as being accessible.
I won't go into detail on the accessibility features here and why I used them. However, for the comparison, I will explain a little about the structure. You will see there is only one anchor tag (around the post title). For sighted users, though, to give the appearance of the link, we change the cursor to a pointer when the mouse is within the component. On top, we use JavaScript to take the user to the blog post when they click anywhere within the component. That helps us achieve the goal of having the component behave as expected by the user.
This behaviour is implemented using onClick
event handlers in the Gatsby
(React) version. In the Svelte version, we on:mouseenter
, on:mouseleave
and on:mousedown
inline handlers.
React equivalent
β click to expandΒ code.
π₯ Static vs Server Side RenderedΒ #
With SvelteKit you can choose to make pages Server Side Rendered, like Next apps typically are, or
static (Static Site Generated, SSG), like Gatsby apps typically are. There is an excellent write up SSG by React guru Dan Abramov , worth the read, even if you already know about SSG. For SSG pages, the SvelteKit Netlify
adapter produces a serverless function which acts as the server. I have made all pages in the
starter static. This was done by adding the @sveltejs/adapter-static
package in svelte.config.js
and also this export in `src/routes/+layout.js:
π§ Self Hosted FontsΒ #
Self-hosting makes the page load faster, saving the user's browser having to connect to a different origin to download the fonts it needs. In SvelteKit, it's not too different. Once again, we install the font packages, we just include them differently. In SvelteKt, we can add them to the default layout file if they are used throughout the site:
π SCSS StylingΒ #
I'm a fan of SCSS so, we are using SCSS styling in the starter. There are a few things you need to do to get this to work in SvelteKit (this is all already done in the starter, just listed for information here):
-
Install the
sass
and Svelte preprocessor packages: -
Set up the Svelte preprocessor to convert SCSS into standard CSS:
The file given in line
8
can be used to include any variables which you want to expose to every style element. -
Define any global styles in the files in
src/lib/styles
directory. -
Import styles where components or pages require them:
-
Include SCSS where you would write regular CSS, specifying
scss
as the language:Note how we can include SCSS variables now.
π Content Security PolicyΒ #
A Content Security Policy can break your site or make it unusable, so it is important to test
the policy. Reporting is helpful here, and the starter is set up to use Sentry reporting. They
offer free reporting, suitable for many use cases. You will need a free Sentry account and API keys for security error catching . Alternatively, remove the reporting lines from the src/hooks.js
file.
CSP is set to report only in the starter by default. This means errors will appear in the
browser console and the reports will get sent to your Sentry dashboard when there is an error
(but no connections will be blocked). You can test your HTTP security headers on securityheaders.com . Once you are happy with the policy, you should switch from Content-Security-Policy-Report-Only
to Content-Security-Policy
. Remember to comment out the
report only line when you do this.
To include Security headers, we can use the Svelte hooks handle . The hooks.server.js
file is in the default location, so you should
not have to include it in svelte.config.js
. The Climate
SvelteKit Blog Starter SvelteKit config, includes it just for completeness, though. You will
almost certainly need to customize the CSP HTTP headers in the hooks file for your application.
src/hooks.server.js
β click to expandΒ code.
As it stands, the generated sites get an A rating from SecurityHeaders.com. It should be
possible to improve this by adding hashes for all inline styles and scripts and removing unsafe-inline
. I will look into how to do this when I get a chance! If you have already written a custom
script to handle it, I would love to hear from you!
For a more comprehensive look at CSP with SvelteKit, see the SvelteKit Content Security Policy post.
πΌ Responsive ImagesΒ #
One area where Gatsby is still ahead of Svelte is on responsive images. I guess we have to wait
a little for someone smart to write something like the Gatsby Image API for SvelteKit. In the
meantime, I have cobbled together a responsive image component using Imgix for hosting. You will
need an Imgix account and to have your images in the cloud somewhere (e.g. AWS S3 or Backblaze)
for this to work for you. As normal, place your credentials in the .env
file (see .env.EXAMPLE
for a template).
Imgix generates images in the best format based on the user's browser. Their CDN serves images
around the globe with haste. The BannerImage
component is able to
query Imgix for the image url and srcset
to create a responsive image.
As a temporary hack, I have manually generated these data so that the entire site can be static (this
is related to the Netlify adapter issue mentioned earlier). If you also want to keep your site static,
you have a choice of either also generating the data manually (or with a script) or using an alternative
method for generating images.
π³ PollΒ #
βοΈ Gatsby β SvelteKit ComparisonΒ #
So now you have a choice between two starters for your next markdown-based blog site Gatsby Starter Climate and SvelteKit Blog Climate — which do you choose? You might say go on speed. Well the Lighthouse test shows them both getting clean sheets with 100s across the board! Gatsby does have some optimizations built in, with links preloading, but then Svelte sites run pure JavaScript, so you would expect them to load slightly quicker (I admit I am no expert on this matter). So on speed, there is probably not much in it. If speed is critical for your project, it will definitely be worth doing the research.
I would say in time SvelteKit will offer the better developer experience, that's not to say that it is not already outstanding! Builds are a lot faster (the Svelte starter builds in around 40 seconds consistently on Netlify, compared to a range of between one minute and three-and-a-half minutes for the Gatsby starter). For bigger sites, I would imagine the difference will have an impact, especially when you have to pay per build minute.
Gatsby is more established so already has a large ecosystem of plugins and on top there are all the React plugins. I think this gives Gatsby the advantage now if you need to build a new site quickly or generally rely on plugins. I would expect the Svelte ecosystem to grow. As it does, there will probably be clear water appearing between the two on developer experience. With that in mind, it is probably worth learning Svelte and SvelteKit to future-proof yourself. This is especially the case if you do not heavily rely on plugins for the sites you build, and like to roll your own components.
ππ½ FeedbackΒ #
Please send me feedback! What do you think of the new starter? I mentioned a few improvements I have in mind. I would also love to hear your opinion on how we can improve it. Have you found the post useful? Would you like to see posts on another topic instead? Get in touch with ideas for new posts. Also, if you like my writing style, get in touch if I can write some posts for your company site on a consultancy basis. Read on to find ways to get in touch, further below. If you want to support posts similar to this one and can spare a couple of dollars, rupees, euros or pounds, please consider supporting me through Buy me a Coffee.
Finally, feel free to share the post on your social media accounts for all your followers who will find it useful. As well as leaving a comment below, you can get in touch via @askRodney on Twitter and also askRodney on Telegram . Also, see further ways to get in touch with Rodney Lab. I post regularly on SvelteKit as well as Gatsby JS among other topics. Also, subscribe to the newsletter to keep up-to-date with our latest projects.