title | description | date | tags | image | draft | |
---|---|---|---|---|---|---|
Getting Started |
A guide on how to use this sveltekit + markdown blog. |
2023-11-20 |
|
false |
Welcome, this will guide you through this template and how to use it. This is a SvelteKit + MDsveX Personal website and a blog completely designed with Shadcn-Svelte, it has everything you need get started and you can fully customise it.
to get started, clone the repo: repo link
git clone https://github.com/PrabhuKiran8790/prabhukirankonda-portfolio.git
it's got ton of features that you don't wanna miss out.
-
Tailwind CSS for styling
-
Shadcn-Svelte for UI Components
-
Light and Dark mode
-
Syntax Highlighting
- with toast notifications for copy feedback
- individual words highlighting
def fibonacci(n): if n <= 1: # base case return n else: return fibonacci(n - 1) + fibonacci(n - 2)
- inline syntax highlighting example:
console.log("Hey there"){:js}
- ability to inlcude an icon if title with an extension is provided.
```js title="example.js" console.log('Hello from JS'); ```
will render into
console.log('Hello from JS');
you can add icons for other languages as well
-
MDsveX to support markdown files so that you can write your blogs in markdown.
-
Custom Components
-
use svelte components inside markdown
- example
try changing the theme 👉 -
Table of Contents
-
Giscus Comments (based on Github Discussions)
-
Image Optimization
-
Support for Nested routing of blogs
-
Projects Page
-
Support for math
\nabla \cdot \mathbf{E} = \frac{\rho}{\varepsilon_0}
\nabla \cdot \mathbf{B} = 0
\nabla \times \mathbf{E} = -\frac{\partial \mathbf{B}}{\partial t}
\nabla \times \mathbf{B} = \mu_0 \left(\mathbf{J} + \varepsilon_0 \frac{\partial \mathbf{E}}{\partial t}\right)
- wondering what those equations are? Maxwells Equations 🙃
- <Math eq={
$\\nabla \\cdot \\mathbf{E} = \\frac{\\rho}{\\varepsilon_0}$
}/> this is an example of inline equation (using external component) -
$$\nabla \times \mathbf{B} = \mu_0 \left(\mathbf{J} + \varepsilon_0 \frac{\partial \mathbf{E}}{\partial t}\right)$$ is an inline equation (I somehow created a plugin to render inline equation without relying on external component.)
-
Mobile friendly interface
in home page at src/routes/+page.svelte
we have two components, Hero
and LatestPost
<script lang="ts">
import { Hero, LatestPost } from '$lib/components/site';
import type { PageData } from './$types';
export let data: PageData;
</script>
<div class="p-4">
<Hero />
<LatestPost {data} />
</div>
here i'm not going with the sveltekit internals, i assume you know the basics.
the Hero
component render the profile picture, Intro and social icons. to chage the social icons, change config.ts
file.
import { LinkedIn, X } from '$lib/components/site/icons';
import { FileText, Github, Mail } from 'lucide-svelte';
type routesType = {
name: string;
link: string;
};
type socialsType = {
href: string;
icon: typeof Github;
display: string;
class?: string;
};
// nav routes
export const routes: routesType[] = [
{
name: 'Blog',
link: '/blog'
},
{
name: 'Projects',
link: '/projects'
},
{
name: 'About',
link: '/about'
}
];
// social icons with links
const socials: socialsType[] = [
{
href: 'https://github.com/prabhukiran8790',
icon: Github,
display: 'GitHub'
},
{
href: 'https://linkedin.com/in/PrabhuKiranKonda',
icon: LinkedIn,
display: 'LinkedIn'
},
{
href: 'https://x.com/prabhukirantwt',
icon: X,
display: 'Twitter',
class: 'h-4 w-4'
},
{
href: 'mailto:prabhukiran426@gmail.com',
icon: Mail,
display: 'Mail',
class: 'h-4 w-4'
},
{
href: '/Prabhu Kiran Konda Resume.pdf',
icon: FileText,
display: 'Resume'
}
];
export const getSocials = ({ exclude }: { exclude?: string } = {}): socialsType[] => {
if (exclude) {
return socials.filter((social) => social.display !== exclude);
}
return socials;
};
export const githubConfig = {
username: 'PrabhuKiran8790',
repo: 'sveltekit-portfolio',
branch: 'main'
};
To ensure that your local images, located in the posts/[slug]
folder, can be converted to GitHub URLs, it's essential to include your githubConfig
in the config.ts
file. This is particularly useful when you want to include images in your blog posts and prefer to store them in the same folder as your post for better organization.
However, there's a caveat – assets in other than public folder (static), won't be processed by Vite. As a result, these images won't have a definite URL. To obtain the URL, you'll need to incorporate your githubConfig
, which transforms your local images into GitHub raw URL format. This ensures that when you deploy your application, the images will correctly point to your GitHub repository.
Alternatively, you can place your images directly in the static folder and access them using /
which points to static folder. example: /image.png
to create a new blog, create a folder with the slug you want and create a page.md
file. the slug will acts as the blog url which will be /blog/[slug]
├── README.md
├── about
├── node_modules
├── posts
│ ├── authjs-sveltekit-prisma <!-- slug -->
│ │ └── page.md
│ ├── dimensionality-reduction-using-auto-encoders <!-- slug -->
│ │ └── page.md
│ └── getting-started <!-- slug -->
│ └── page.md
├── src
├── static
├── package.json
├── components.json
├── pnpm-lock.yaml
├── postcss.config.cjs
├── svelte.config.js
├── mdsvex.config.js
├── tailwind.config.js
├── tsconfig.json
└── vite.config.ts
Frontmatter allows you to specify metadata and options. Included in frontmatter are things like the document or project title, what thumbnail to use for site or content previews, authors that contributed to the work etc,
for this template the frontmatter is
---
title:
description:
date: '2023-11-26'
tags:
- SvelteKit
image: url or a pathname
draft: false
---
tags
is an array so if you want to declare multiple tags just add a new tag below it and of course you can change these but you need to change the Post type as well accordingly.
you can find the Post
type in src/lib/types.ts
export type Post = {
title: string;
// slug is not related to the frontmatter but is included to get the slug via an api
slug: string;
description: string;
date: string;
tags: string[];
image: string;
draft: boolean;
};
Syntax highlighting is made possible using shiki and rehype-pretty-code plugin.
a small example:
```ts title="hello.ts" showLineNumbers {1} /Hello/#yb
console.log('Hello');
```
will render into
console.log('Hello');
and for code diffing,
```js title="code-diff.js"
export function foo() {
console.log('hewwo') // [!code --] // this should be hello
console.log('hello') // [!code ++]
}
```
this will become
export function foo() {
console.log('hewwo') // [!code --] // this should be hello
console.log('hello') // [!code ++]
}
it is important to add
// [!code --]
and// [!code ++]
to see the changes, that inlcudes the whitespace after the comment
you can change these styles in markdown.postcss
file and pre.svelte
file and for more information visit rehype-pretty-code
-
to write inline math equations,
<script> import { Math } from '$lib/components/markdown'; </script> <Math eq={`$\\\nabla \\\\cdot \\\\mathbf{E} = \\\\frac{\\\rho}{\\\\varepsilon_0}$`} /> this is an example of inline equation
-
add a script tag inside your markdown and import the
Math.svelte
component and write your LaTeX equation. -
you can add path aliases to shorten the path if you use it more often.
-
the above equation will become
- <Math eq={
$\\nabla \\cdot \\mathbf{E} = \\frac{\\rho}{\\varepsilon_0}$
}/> this is an example of inline equation - <Math eq={
$$\\nabla \\cdot \\mathbf{E} = \\frac{\\rho}{\\varepsilon_0}$$
}/> this is an example of inline equation - to make the inline equations bigger, wrap the equation in
$$
instead of single$
- <Math eq={
-
the reason why we're adding double backslashes (
\\
) is to avoid unicode escape sequence.Note: one thing to make sure that, you cannot add inline equations in a list. Well, you might be thinking that above inline equation is indeed a list item, then what's the problem? The problem comes when we add inline equation in a list item that already has content.
-
below inline equation will not work
- this will not work <Math eq={`$\\\nabla \\\\cdot \\\\mathbf{E} = \\\\frac{\\\rho}{\\\\varepsilon_0}$`}/> this is an example of inline equation
- but this will work
- <Math eq={`$\\\nabla \\\\cdot \\\\mathbf{E} = \\\\frac{\\\rho}{\\\\varepsilon_0}$`}/> this is an example of inline equation
-
I don't know the reason but if there's any fix i'll update or you can fix it and make a pull request.
-
but when it comes to block equations, there is no need to do this. it's pretty easy. all you need to do is
```math \nabla \times \mathbf{B} = \\mu_0 \\left(\\mathbf{J} + \\varepsilon_0 \\frac{\\partial \\mathbf{E}}{\\partial t}\\right) ```
- define a codeblock with
math
as the language and the above equation becomes
\nabla \times \mathbf{B} = \mu_0 \left(\mathbf{J} + \varepsilon_0 \frac{\partial \mathbf{E}}{\partial t}\right)
To render inline equations without using any component, you can use this below
$$\nabla \\times \\mathbf{B} = \\mu_0 \\left(\\mathbf{J} + \\varepsilon_0 \\frac{\\partial \\mathbf{E}}{\\partial t}\\right)$$
- this is as of Dec 5, 2023. I added a new plugin to render inline maths.
- this will fix the above mentioned issue of not rendering inline math equation in list item with content.
- example:
$$\nabla \times \mathbf{B} = \mu_0 \left(\mathbf{J} + \varepsilon_0 \frac{\partial \mathbf{E}}{\partial t}\right)$$ this will work - you don't even need to put double backslashes
\\
, just write like you write them in math blocks, but wrap between double dollar signs. - this is the recommended way from now on.
-
Comments are made possible using Giscus, a GitHub discussion based commenting system. Start by changing some environment variables to setup Giscus. In you .env
file change the following variables. These environment variables are imported in routes/blog/[slug]/+page.svelte
PUBLIC_GITHUB_REPO = prabhukirankonda-portfolio
PUBLIC_GITHUB_USERNAME = PrabhuKiran8790
PUBLIC_GITHUB_REPO_ID =
PUBLIC_CATEGORY = General
PUBLIC_CATEGORY_ID =
to get Repo ID, Category ID goto Giscus and follow the instructions.
To add a new project, you can start by chaging the src/lib/projects.ts
file.
import type { TechStack } from './types';
export type ProjectType = {
title: string;
href: string;
image: string;
description: string;
techstack: TechStack[];
};
export const projects: ProjectType[] = [
{
title: 'Personal Portfolio with Markdown Blog',
description:
'This website, prabhukirankonda.vercel.app is my personal website with a markdown blog written in SvelteKit and deployed using Vercel. Styled using Taiwind CSS and Shadcn-UI and completely written in TypeScript.',
href: 'https://prabhukirankonda.vercel.app',
image: '/sveltekit-portfolio.png',
techstack: ['SvelteKit', 'Tailwind', 'TypeScript']
}
];
make sure the techstack is of type TechStack[]
so that it's possible to render the respective icons to showcase projects. see /projects
to get an idea on how icons are rendered and see src/lib/types.ts
for more information.
About page is also rendered using markdown but it has its own layout. src/lib/components/markdown/about-layout.svelte
. To change about edit about/about.md
. if you see the fronmatter for about.md
there's a layout: about
which tells the MDsveX preprocessor to use about layout.
about layout is defined in mdsvex.config.js
/** @type {import('mdsvex').MdsvexOptions} */
export const mdsvexOptions = {
extensions: ['.md', '.svx'],
layout: {
_: resolve('./src/lib/components/markdown/layout.svelte'), //default or fallback layout
about: resolve('./src/lib/components/markdown/about-layout.svelte') // named layout
},
remarkPlugins: [],
rehypePlugins: []
};
These are the some of the important changes to be made to get started. If you have any issues, feel free to open an issue. In the next update, I'll include related posts based on tags.