Opens an external site in a new window
Mental Health Awareness Month
“Community”
RODNEY LAB
  • Home
  • Plus +
  • Newsletter
  • Links
  • Profile
RODNEY LAB
  • Home
  • Plus +
  • Newsletter
  • Links

SvelteKit Tutorial: Build a Svelte MDsveX Blog Site # SvelteKit Tutorial: Build a Svelte MDsveX Blog Site #

blurry low resolution placeholder image SvelteKit Tutorial: Build a Svelte MDsveX Blog Site
  1. Home Rodney Lab Home
  2. Blog Posts Rodney Lab Blog Posts
  3. SvelteKit SvelteKit Blog Posts
<PREVIOUS POST
NEXT POST >
LATEST POST >>

SvelteKit Tutorial: Build a Svelte MDsveX Blog Site #

Updated 4 months ago
6 minute read
Gunning Fog Index: 6
2 comments
Content by Rodney
blurry low resolution placeholder image Author Image: Rodney from Rodney Lab
SHARE:

🧑🏽‍🎓 SvelteKit Tutorial #

SvelteKit Tutorial: with all the buzz around SvelteKit, we'll run through how to set up an accessible, fast and secure Svelte Blog using SvelteKit. Our posts will be powered by Svelte in markdown (MDsveX). Essentially, this new project is an extension on the recent blog post where we looked at the SvelteKit MDsveX Blog starter. This time we are taking a more hands-on approach, customizing the site and adding some MDsveX to the blog posts. If that sounds like the kind of thing you can get excited about, let's get going!

🚀 Let’s Get the Ball Rolling! #

To hit the ground running, we will be using the MDsveX Blog Starter. So, the first thing we need to do is clone it. I will be using pnpm as the package manager, but if you prefer npm, just drop the first p from all the pnpm commands. Let's clone the repo and set it up at the command line:

    
git clone https://github.com/rodneylab/sveltekit-blog-mdx.git sveltekit-tutorial
cd sveltekit-tutorial
pnpm install
cp .env.EXAMPLE .env
pnpm dev

If this is your first time using SvelteKit, you might find it useful to skim through the post on Getting Started with SvelteKit. However, if anything is unclear, please get in touch (see details below), as it could be something I forgot to mention! Now, in your browser, go to localhost:5173.

As you have the site open, have a look though the pages. You will see there is some demo content in there already. In this post, we will:

  • update styling;
  • change fonts; and
  • add a new Svelte component and use it in an MDsveX blog post.

If you're as keen as I am, then let's jump onto the next part and see how you update the styling in the starter.

💄 Styling #

We use SCSS for styling in the starter. Much of the styling is set by variables in two files: src/lib/styles/styles.scss and src/lib/styles/variables.scss. Styles propagate globally from there. This makes it easy to update the site's styling. Let's start by changing the colours up. Edit src/lib/styles/variables.scss:

src/lib/styles/variables.scss
scss
    
79 // Colours
80 $color-theme-1: #e63946; // imperial red
81 $color-theme-2: #a8dadc; // powder blue
82 $color-theme-3: #457b9d; // celadon blue
83 $color-theme-4: #1d3557; // prussian blue
84
85 $color-primary: #005b99;
86 $color-text: #0d1821; // rich black FOGRA 29
87 $color-heading: $color-theme-4;
88 $color-heading-black: $color-theme-4;
89 $color-accent: #f1faee; // honeydew
90 $color-success: #2ec4b6; // tiffany blue
91 $color-danger: #e71d36; // rose madder

Excuse the inconsistent spelling of the word “colour”! Do other non-Americans do this, or is it just me? 😀

Next, let’s remove the italic styling for level 1 headings, deleting that line so that src/lib/styles/styles.scss ends up looking like this:

src/lib/styles/styles.scss
scss
    
58 h1 {
59 margin-top: 0;
60 font-weight: variables.$font-weight-black;
61 font-size: variables.$font-size-6;
62 color: variables.$color-heading-black;
63 }

No peeking until we have finished! Next, we will change the BlogPostSummary and Card components:

src/lib/componetns/BlogPostSummary.svelte
svelte
    
41 // TRUNCATED...
42 <span id={idString} aria-hidden="true" class="read-more-text">Read more {H_ELLIPSIS_ENTITY}</span>
43 </div>
44 </div>
src/lib/componetns/BlogPostSummary.svelte
svelte
    
53 .content {
54 width: 100%;
55 border-radius: variables.$spacing-2;
56 margin: variables.$spacing-0 auto;
57 padding: variables.$spacing-4 variables.$spacing-0;
58
59 h3 {
60 margin: variables.$spacing-0 variables.$spacing-2;
61 }
62 p {
63 color: variables.$color-theme-3;
64 font-size: variables.$mobile-font-size-2;
65 margin: variables.$spacing-2;
66 }
67 .read-more-text {
68 margin: variables.$spacing-2;
69 }
70 }
71
72 .content:hover {
73 h3 {
74 color: variables.$color-accent;
75 }
76 p {
77 color: variables.$color-theme-2;
78 }
src/lib/componetns/Card.svelte
svelte
    
17 .content {
18 width: 100%;
19 background-color: variables.$color-theme-2;
20 border-radius: variables.$spacing-1;
21 margin: variables.$spacing-0 auto;
22 padding: variables.$spacing-4;
23 }

Then finally, let's spruce up the home page, whose code is at src/routes/+page.svelte. We're changing up the title and restyling the “About Me” card:

src/routes/+page.svelte
svelte
    
1 <header>
2 <h1>My Film Photography Blog</h1>
3 </header>
4 <Card>
5 <div class="card">
6 <h2><span>About me</span></h2>
7 <p>
8 I live and breathe analogue photography. I show you my favourite analogue film cameras on this
9 site. Hopefully if you are not into analogue photography yet, some of my enthusiasm will rub off
10 onto you.
11 </p>
12 </div>
13 </Card>
14 <BlogRoll {posts} />
15
16 <style lang="scss">
17 .card h2 { margin-top: variables.$spacing-0; }
18 </style>

OK, you can have a look in the browser now. What do you think? Change it up a little more if it's not yet your cup of tea! When you're ready to move on, we'll change the fonts.

🖋 Fonts #

The starter uses self-hosted fonts. This allows the page to load faster, improving user experience. One thing you need to remember is to install the new fonts when you change them. Let's start by uninstalling the starter fonts, which we no longer want at the command line:

    
pnpm uninstall @fontsource/lora @fontsource/source-sans-pro

Next, as you probably guessed, we will install a replacement font:

    
pnpm install @fontsource/slabo-27px

We will also use Lato, but that is already installed. Slabo 27px will be used for headings and Lato for other elements. Most free fonts are available as Fontsource packages, you see the Fontsource website for more details . Be sure to check which weights and styles are supported for your chosen font.

Now we have the fonts installed, we need to import them and then set them as our chosen fonts in the SCSS variables file. Let's start with the variables file:

src/lib/styles/variables.scss
scss
    
36 // Fonts
37 $font-family-serif: 'Lato', 'Lustria', 'Noto Serif', 'Merriweather', 'Georgia', 'Cambria',
38 'Times New Roman', 'Times', serif;
39 $font-body: $font-family-serif;
40 $font-heading: 'Slabo 27px', $font-family-serif;

Let's carry on to the final step; importing the fonts. Since all pages use our global layout file (src/routes/+layout.svelte), we will import fonts there, removing the original import:

src/routes/+layout.svelte
svelte
    
41 <script>
42 // Lato - supported variants:
43 // weights: [100, 300, 400, 700, 900]
44 // styles: [italic, normal]
45 import '@fontsource/lato/400.css';
46
47 // Slabo 27px - supported variants:
48 // weights: [400]
49 // styles: [normal]
50 import '@fontsource/slabo-27px/400.css'
51 // TRUNCATED...

⚓️ Headings with Scroll to Anchor #

Sadly, we're almost finished. Let's carry on with the next step. I promised we would create a new svelte component and add it to our blog post markup. We will do exactly that now. We will implement scroll to anchor. You have probably been on websites on which if you hover over a title, a little link icon appears. You can copy that link to reference it from somewhere else, or just click it so the section you are reading scrolls to the top of the screen. That's just what we will set up now. Let's start by creating the new Heading component. Make a new file at src/lib/components/Heading.svelte:

src/lib/components/Heading.svelte
svelte
    
1 <script>
2 import LinkIcon from '$lib/components/Icons/Link.svelte';
3
4 export let id;
5
6 $: showLink = false;
7
8 const handleMouseEnter = (event) => {
9 showLink = true;
10 }
11
12 const handleMouseLeave = (event) => {
13 showLink = false;
14 }
15 </script>
16
17 <h2
18 {id}
19 on:mouseenter={handleMouseEnter}
20 on:mouseleave={handleMouseLeave}
21 >
22 <slot />
23 {#if showLink}
24 <a href={`#${id}`}>
25 <LinkIcon />
26 </a>
27 {/if}
28 </h2>

That code fragment is packed full of sveltisms. There's a bit too much to go into here. It's worth checking the Svelte tutorial for explanations , though also feel free to get in touch if I can help. We rely on default browser behaviour for the scrolling. An id will be supplied by the component consumer. We label our heading with that id. Because of that, the browser knows where to scroll when we specify that id in the anchor element.

This is quite a basic version to demonstrate MDsveX. You can go to town here when you implement it on your own site. For example, you might want to generate the IDs automatically or have custom heading levels. There is so much you can do with this one tiny element.

You will notice we imported a Link icon, which we need to add the icon to our project. Let's get cracking on that.

Link Icon #

Create a new file at src/lib/components/Icons/Link.svelte and give it the following content to import the corresponding Feather icons icon:

src/lib/components/Icons/Link.svelte
svelte
    
<script>
import { DEFAULT_ICON_SIZE } from './index.js';
import LinkIcon from 'svelte-feather-icons/src/icons/LinkIcon.svelte';
export let size = DEFAULT_ICON_SIZE;
</script>
<LinkIcon {size} />

Our final step is to import the component in a blog post and use it. Open up src/routes/best-medium-format-camera-for-starting-out/index.md. The file is a little messy, with a lot of front matter because of a temporary workaround for the Netlify adapter. That aside, let's import and use the Heading element:

src/routes/best-medium-format-camera-for-starting-out/index.md
svelte
    
36 <script>
37 import ExternalLink from '$lib/components/ExternalLink.svelte';
38 import Heading from '$lib/components/Heading.svelte';
39 import Link from '$lib/components/Link.svelte';
40 </script>
41
42 <Heading id="whatIsAMediumFormatCamera">What is a Medium Format Camera? </Heading>
43 // TRUNCATED...

Now go to your browser and hover over the link and the link icon should appear, you can click it to scroll to anchor. When you move the mouse away from the link, it should disappear. Hope it's all working. What do you think?

🙌🏽 SvelteKit Tutorial: Wrap Up #

blurry low resolution placeholder image SvelteKit Tutorial: Build a Svelte MDsveX Blog Site.
Screenshot: SvelteKit Tutorial: Build a Svelte MDsveX Blog Site

That's it for now. Normally, I would also run automated accessibility tests in Cypress using Axe. Unfortunately, Cypress is not currently compatible with SvelteKit out of the box, though there are a few workarounds you can try . As an alternative, you can install the Axe browser addin, then open up Axe from your browser Dev Tools.

I am keen to hear how you will extend what we have run here, though. What will you blog about?

🙏🏽 SvelteKit Tutorial: Feedback #

Please send me feedback! 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.

Thanks for reading this post. I hope you found it valuable. Please get in touch with your feedback and suggestions for posts you would like to see. Read more about me …

blurry low resolution placeholder image Rodney from Rodney Lab
TAGS:
SVELTEKITACCESSIBILITY

Reposts:

Reposts

  • Bruno Canini profile avatar
  • Richard profile avatar
  • Svelte Society 🧡 profile avatar

Likes:

Likes

  • Bruno Canini profile avatar
  • JoRiviera profile avatar
  • patrick bateman profile avatar
  • zhuganglie profile avatar
  • nicobruenjes 🤬 profile avatar
  • Colin Fahrion profile avatar
  • Richard profile avatar
  • Morgan profile avatar
  • Benjamín Salas Sadler profile avatar
  • David Stevens profile avatar
  • Jorge Paredes profile avatar
  • opensas profile avatar
  • Quang Phan profile avatar
  • Alessandro Casazza profile avatar
  • Svelte Society 🧡 profile avatar
  • Michael Bloomfield profile avatar
  • Jordan Shurmer profile avatar
Reposts & likes provided by Mastodon & X via Webmentions.

Related Posts

blurry low resolution placeholder image Get Started with SvelteKit Headless WordPress

Get Started with SvelteKit Headless WordPress

plus
sveltekit
<PREVIOUS POST
NEXT POST >
LATEST POST >>

Leave a comment …

Your information will be handled in line with our Privacy Policy .

Comments

  • Richard Nash

    Hi Rodney, Have you messed around at all with trying to add auto-generated TOC's to your blog posts at all using Sveltekit and mdsvex? Starting down that path, but not sure where to turn to...

    4 years ago
    • Rodney

      Hi Richard, good question! I've had a look and it's not too difficult to do. Basically if you are using the mdsvex plugin already, you just need to add the @jsdevtools/rehype-toc package and set your mdsvex options to use it. I have setup and tested adding a table of contents on this branch. Take a look at the svelte.config.js file in the project root. Let me know if it needs more explanation.
      4 years ago

Ask for more

1 Nov 2022 — Astro Server-Side Rendering: Edge Search Site
3 Oct 2022 — Svelte eCommerce Site: SvelteKit Snipcart Storefront
1 Sept 2022 — Get Started with SvelteKit Headless WordPress

Copyright © 2020 – 2025 Rodney Johnson. All Rights Reserved. Please read important copyright and intellectual property information.

  • Home
  • Profile
  • Plus +
  • Newsletter
  • Contact
  • Links
  • Terms of Use
  • Privacy Policy
We use cookies  to enhance visitors’ experience. Please click the “Options” button to make your choice.  Learn more here.