Skip to content

A SvelteKit blog template with markdown rendering and dynamically imported images.

Notifications You must be signed in to change notification settings

KoljaL/LK-Blog-SvelteKit

Repository files navigation

Rasal Blog

Just another blog, made with SvelteKit.
Just for my personal use or for anyone who wants to use it.
MIT License

Used technologies

  • SvelteKit web development, streamlined
  • SvelteKit adapter-static for static site generation
  • MDSvex for markdown rerndering
  • vite-Imagetools for image optimization
  • Svelte-DebugBar for debugging like in Laravel
  • Dark & Light Mode
  • Code Highlighting & copy to clipboard

Components

  • Nested menu with endless depth, based on folder structure.
  • Grid of card with article excerpt and image, sortable by date, category, tags or tag.
  • Meta Tags for SEO

Files & Folder Structure

  • All articles are stored in src/articles as markdown files
  • The folder structre is just for grouping the articles and has no effect on the url
  • The file name of each article has to be index.md
  • All article related images are stored in the same folder as the article
  • Routes for article ([...article]), tags ([t]) and categories ([c]).
  • Layout templates for articles are stored in src/lib/layouts.
  • They are defined in the frontmatter of the article and declared in mdsvex.config.js.

Data Structure

  • +layout.ts: reads all ìndex.md files inside the src/articles folder and creates an array of all articles meta data.
  • $page.data.ArtilcesMetaData: stores this array, so it can be used in any component.
  • +layout.svelte: is the main layout file and contains the header, footer and the main content.
  • +page.svelte: is the starting point for all pages and contains a welcome text and the grid of cards.
  • lib/Components/GridOfCards/Grid.svelte creates a nested array from the articles meta data, based on the folder structure and displays the cards (ArticleCard.svelte) as a grid.
    • The Grid-Component has a sort prop, which can be used to sort the cards by date, category, tags or tag.
  • [...article]/+page.ts: Uses the slug from the url to find the article in the ArticlesMetaData and imports the article content.
    • It returns ArticlesMetaData (all), ArticleMeta(current) and ArticleComponent(content).
  • +page.svelte: uses the ArticleComponent to render the article content and sends the ArticleMeta to <Meta /> to create the meta tags.
  • c/[category] and t/[tag] are almost identically. They use the category or tag from the url to filter the ArticlesMetaData and send the filtered array to <Grid /> to display the cards.
  • src/lib/layouts/default.svelte is the default layout and will be used for all pages, which don't have a layout defined in the frontmatter.

Frontmatter

Required Frontmatter

  • published
  • layout
  • title
  • tags
  • category
  • description
  • excerpt
  • created
  • edited
  • imagePath
  • imageAlt
  • imageDescription

Generated Frontmatter

  • articlePath
  • articleSlug
  • articleUrl
  • imageUrl
  • siteName
  • siteUrl
  • author
  • authorTwitter

Types

export type ArticleMetaData = {
	published: boolean;         // only published articles will be rendered
	layout?: string;            // default, Code, Planet, ...
	title: string;              // must be unique for each article
	author?: string;            // from blog.config.js
	authorTwitter?: string;     // from blog.config.js
	tags: string;               // comma separated
	description: string;        // short description for meta tags and hover
	excerpt: string;            // for GridOfCards
	created: any;               // dd.mm.yyyy
	edited?: any;               // dd.mm.yyyy
	imagePath: string;          // relative path to the image without dot: /Jupiter.jpg 
	imageUrl?: string;          // for meta tags
	imageAlt: string;           // for meta tags
	imageDescription: string;   // for meta tags and hover
	articlePath?: string;       // generated: /src/articles/Code/
	articleSlug?: string;       // generated from title
	articleUrl?: string;        // generated: for meta tags
	siteName?: string;          // from blog.config.js
	siteUrl?: string;           // from blog.config.js
	// category: string;        // not used yet
};

export type GridSort = 'Recent' | 'Category' | 'Tag' | 'Tags';

export type ArticleMetaSorted = {
	sorted: GridSort;
	articles: ArticleMetaData[];
};

Links I used through the development

// https://github.com/JonasKruckenberg/imagetools/issues/5#issuecomment-1522596146
const images = import.meta.glob('../example/path/*.png', {
	query: { width: '100,200,300' },
	eager: true,
});

return {
	image: images[`../example/path/${myVar}.png`]?.default || null,
};