SvelteKit TypeScript vanilla-extract Starter: Markdown Blog
Tags: webdev, css, typescript, svelte
Published: 2022-06-30 15:37:53

---
title: "SvelteKit TypeScript vanilla-extract Starter: Markdown Blog"
published: "true"
description: "SvelteKit TypeScript vanilla-extract starter: create a markdown blog site with responsive, Next-Gen images, PWA and vanilla-extract styles."
tags: "webdev, css, typescript, svelte"
canonical_url: "https://rodneylab.com/sveltekit-typescript-vanilla-extract-starter/"
cover_image: "https://dev-to-uploads.s3.amazonaws.com/uploads/articles/59r93zxq3h3jlmjje2qu.png"
---

## 🤝 Introducing new SvelteKit TypeScript vanilla-extract Starter

In this post we take a look at getting up and running with the new SvelteKit **TypeScript vanilla-extract starter**.  Vanilla-extract is a CSS in JavaScript or more specifically **CSS in TypeScript** styling framework.  It uses TypeScript to help developers scope styles and **enforce coding style**.  At build-time, vanilla-extract **generates CSS stylesheets** from your input TypeScript.  Because it generates CSS, there is **zero runtime overhead**, meaning a fantastic experience for end users.

Since vanilla-extract uses TypeScript for styling input, it makes sense also to use TypeScript for the SvelteKit side and leverage autocompletion and type safety together with the other **TypeScript benefits**.  In the rest of this post we look at getting started with the new starter from cloning the repo to build.

![SvelteKit TypeScript vanilla-extract Starter: Screen shot of starter homepage in browser, shows Light / dark mode toggle and Home and Contact navigation links.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/panhd9reu4be9ukeqnn5.png)

## 🚀 Quick Start

Get going in three steps: clone the repo, install packages then spin up a dev server to start building out your new project:

```shell
git clone https://github.com/rodneylab/sveltekit-typescript-vanilla-extract-starter.git
cd sveltekit-typescript-vanilla-extract-starter
pnpm install
pnpm run dev
```

This will spin up a dev server on your machine on TCP port `3000`.  If you already have something running there, <a aria-label="Open video on switching Svelte Kit dev server port" href="https://rodneylab.com/sveltekit-port/">it is easy to switch SvelteKit server port</a>, adding a `--port 3001` (or similar) to the project `package.json` dev script.

When you are ready, to build the site, just do a `pnpm run build` from the Terminal.

## 🧐 What's Inside?

```plaintext
.
├── README.md
├── package.json
├── src
│   ├── app.d.ts
│   ├── app.html
│   ├── content
│   │   └── blog
│   │       ├── best-medium-format-camera-for-starting-out
│   │       ├── folding-camera
│   │       └── twin-lens-reflex-camera
│   ├── lib
│   │   ├── assets
│   │   ├── components
│   │   │   ├── BannerImage.css.ts
│   │   │   ├── BannerImage.svelte
│   │   │   ├── ...
│   │   │   ├── PWA.svelte
│   │   │   └── SEO
│   │   ├── config
│   │   │   └── website.ts
│   │   ├── generated
│   │   │   └── posts
│   │   ├── shared
│   │   │   └── stores
│   │   ├── styles
│   │   │   ├── normalise.css
│   │   │   ├── styles.css.ts
│   │   │   ├── themes
│   │   │   └── vars
│   │   └── utilities
│   │       └── blog.ts
│   ├── routes
│   │   ├── [slug]
│   │   │   ├── __layout.svelte
│   │   │   ├── index.json.ts
│   │   │   └── index.svelte
│   │   ├── __layout.svelte
│   │   ├── index.svelte
│   │   └── index.ts
│   └── service-worker.js
├── static
│   ├── apple-touch-icon.png
│   ├── ...
│   └── manifest.webmanifest
├── svelte.config.js
└── tsconfig.json
```

### `src`

- `app.d.ts` here we have custom types used by the app.

- `app.html` regular SvelteKit HTML template, we include some favicon links in the html head section.

### `src/content`

This is where we add new blog posts.  Create a new folder under `src/content/blog` for each new post.  Just add an `index.md` file inside the new directory for the post content.  Although the file has an `.md` extension, since the project uses **mdsvex** you can drop Svelte code in there too.  A new post  in `src/content/blog/new-post/index.md` will be generated on `https://example.com/new-post/`.

### `src/lib/assets`

We have images in here, such as banner images and social sharing images used in the starter&rsquo;s SEO components.

### `src/lib/components`

- `src/lib/components` these are the components we use in pages.  We define style files alongside file components.  As an example, we have the Svelte component file `BannerImage.svelte` for next-gen responsive images and next to it; `BannerImage.css.ts`.  In there we define the component&rsquo;s vanilla-extract styles.  If you use VSCode, in the project&rsquo;s `.vscode/settings.json` there is an override for  `explorer.fileNesting.patterns` which tucks these `.css.ts` files into their parent `.svelte` files.

### `src/lib/generated`

This folder contains a file for each post with responsive data used with vite-imagetools.  vite-imagetools generates images in next-gen formats together with responsive sizes.  The node script `generate-responsive-image-data.ts` actually creates these files.

### `src/lib/shared`

Here we have a Svelte store which puts the use light/dark theme preference to local storage.  The code checks if there is already a browser preference for light or dark theme. This, however, is overridden when the user toggles the dark/light button.  Then, using local storage, we note the choice for future site visits.


### `src/lib/styles`

- `src/lib/styles/styles.css.ts` here you will find the main vanilla-extract global styles.  The file references variables set in `src/lib/styles/vars` folder (such as spacing, font sizes and so on).

- `src/lib/styles/themes` we have a few files here. `theme.css.ts` defines the variables which any theme must have. We start to see some of the power of vanilla-extract here.  The other two files define those variables for the light and dark themes included in the starter.

### `src/utilities`

- `src/utilities/blog.ts` 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 frontmatter (this is the metadata we include at the top of the blog post `index.md` files).

### `src/routes`

- `src/routes/[slug].json.ts` this is essentially a template for blog post data. One of these files is generated at build for each blog post.

If you are new to Svelte, see the post on <a aria-label="Read recent Rodney Lab post on Getting Started with Svelte Kit" href="https://rodneylab.com/getting-started-with-sveltekit/">Getting Started with SvelteKit blog post</a>.  That goes into a little detail on some of the other files in a Svelte project.  By the same token, the post on <a aria-label="Read article on using vanilla-extract with Svelte Kit" href="https://rodneylab.com/using-vanilla-extract-sveltekit">using vanilla-extract in SvelteKit talks more about the benefits of using vanilla-extract</a> for styling.  As well as that there is more detail on the nuts and bolts of making it work with SvelteKit.

## 🖋 SvelteKit TypeScript vanilla‑extract Starter: Blog Posts

We just mentioned the blog posts are in `index.md` files within folders under `src/content/blog`. Here is an example:

```markdown
---
postTitle: 'Best Medium Format Camera for Starting Out'
focusKeyphrase: 'best medium format camera'
datePublished: '2022-05-07T16:04:42.000+0100'
lastUpdated: '2022-05-14T10:17:52.000+0100'
seoMetaDescription: "Best medium format camera for starting out is probably a question at the front of your mind right now! Let's take a look."
featuredImage: 'best-medium-format-camera-for-starting-out.jpg'
featuredImageAlt: 'Photograph of a Hasselblad medium format camera with the focusing screen exposed'
ogImage: 'best-medium-format-camera-for-starting-out-open-graph.jpg'
ogSquareImage: 'best-medium-format-camera-for-starting-out-open-graph-square.jpg'
twitterImage: 'best-medium-format-camera-for-starting-out-twitter.jpg'
categories: ''
tags: ''
---

<script>
  import ExternalLink from '$lib/components/ExternalLink.svelte';
  import Link from '$lib/components/Link.svelte';
</script>

## What is a Medium Format Camera?

If you are old enough to remember the analogue film camera era, chances are it is the 35&nbsp;mm canisters with the track cut down the side that first come to 
```

This looks like <a aria-label="Open the common mark markdown spec" href="https://spec.commonmark.org/current/">regular Markdown</a> at first glance.  However, you might notice we have a familiar Svelte `script` tag in lines `16`&ndash;`19`.  This comes courtesy of mdsvex and lets us use Svelte components within the post content files.  The frontmatter fields (like `seoMetaDescription` and `twitterImage`) are passed to the starter&rsquo;s SEO component.

## 🖼 SvelteKit TypeScript vanilla‑extract Starter: Icons

![SvelteKit TypeScript vanilla-extract Starter: Screen shot of footer icons including Twitter , Tik Tok and Git hub icons.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1nakx5cdugmwil5nk0nk.png)

We use Iconify icons in the starter.  This gives you access to thousands of icons in dozens of libraries all through a single npm package.  The starter uses these icons offline, though you can choose to download them on demand.  See the <a aria-label="Open article on using Iconify with Svelte Kit" href="https://rodneylab.com/sveltekit-svg-icons/">article on using SvelteKit with Iconify</a> for more on customisation together with finding icons.

## 🙌🏽 SvelteKit TypeScript vanilla-extract Starter: Wrapup

We have a had a quick look at getting up and running with the new SvelteKit TypeScript vanilla-extract starter.  In particular we have touched on:

- **cloning and then spinning up** the starter,
- where to find **vanilla-extract** global styles as well as other important files,
- some starter features including **responsive images** and **Iconify icons** together with **light/dark mode**.

This was just a quick look though! Probably the best way to get acquainted with the starter is just to clone it, then start playing around. I would love to hear of your suggestions for improvements.  Do let me know if there is something missing either in the starter or from this introduction.  You can drop a comment below or reach out for a chat on <a aria-label="Jump into the Element Matrix chat room" href="https://matrix.to/#/%23rodney:matrix.org">Element</a> as well as <a aria-label="Mention on Twitter" href="https://twitter.com/intent/user?screen_name=@askRodney">Twitter @mention</a>

You can get the starter from <a aria-label="Open the Rodney Lab Git Hub repo" href="https://github.com/rodneylab/sveltekit-typescript-vanilla-extract-starter" rel="follow noopener noreferrer">the Rodney Lab Git Hub repo</a>.

## 🙏🏽 SvelteKit TypeScript vanilla‑extract Starter: Feedback

If you have found this video useful, see links below for further related content on this site. I do hope you learned one new thing from the video. Let me know if there are any ways I can improve on it. I hope you will use the code or starter in your own projects. Be sure to share your work on Twitter, giving me a mention so I can see what you did. Finally be sure to let me know ideas for other short videos you would like to see. Read on to find ways to get in touch, further below. If you have found this post useful, even though you can only afford even a tiny contribution, please <a aria-label="Support Rodney Lab via Buy me a Coffee" href="https://rodneylab.com/giving/">consider supporting me through Buy me a Coffee</a>.

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 <a aria-label="Reach out on Twitter" href="https://twitter.com/messages/compose?recipient_id=1323579817258831875">@askRodney</a> on Twitter and also <a aria-label="Contact Rodney Lab via Telegram" href="https://t.me/askRodney">askRodney on Telegram</a>. Also, see <a aria-label="Get in touch with Rodney Lab" href="https://rodneylab.com/contact">further ways to get in touch with Rodney Lab</a>. I post regularly on <a aria-label="See posts on svelte kit" href="https://rodneylab.com/tags/sveltekit/">SvelteKit</a> as well as <a href="https://rodneylab.com/tags/seo" aria-label="See posts on search engine optimisation">Search Engine Optimisation</a> among other topics. Also <a aria-label="Subscribe to the Rodney Lab newsletter" href="https://rodneylab.com/about/#newsletter">subscribe to the newsletter to keep up-to-date</a> with our latest projects.