Getting Started

Getting Started

November 20, 2023

P K

Prabhu Kiran Konda

Introduction

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
	
			git clone https://github.com/PrabhuKiran8790/prabhukirankonda-portfolio.git
	

Features

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)
      	
      fib.py
      			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")console.log("Hey there")
    • ability to inlcude an icon if title with an extension is provided.
    			```js title="example.js"
    console.log('Hello from JS');
    ```
    	
    			```js title="example.js"
    console.log('Hello from JS');
    ```
    	

    will render into

    			console.log('Hello from JS');
    	
    example.js
    			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

    E=ρε0 abla cdot mathbf{E} = rac{ ho}{ arepsilon_0} B=0 abla cdot mathbf{B} = 0 ×E=Bt abla imes mathbf{E} = - rac{partial mathbf{B}}{partial t} ×B=μ0(J+ε0Et) abla imes mathbf{B} = mu_0 left(mathbf{J} + arepsilon_0 rac{partial mathbf{E}}{partial t} ight)
    • wondering what those equations are? Maxwells Equations 🙃
    • $\nabla \cdot \mathbf{E} = \frac{\rho}{\varepsilon_0}$

      this is an example of inline equation (using external component)
    • ×B=μ0(J+ε0Et)\nabla \times mathbf{B} = mu_0 left(mathbf{J} + arepsilon_0 rac{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

How to use?

Starting from home page

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>
	
+page.svelte
			<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'
};
	
config.ts
			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

Creating a new blog

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
	
			├── 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
	

Adding frontmatter

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
---
	
			---
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;
};
	
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;
};
	

Code Blocks

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');
```
	
			```ts title="hello.ts" showLineNumbers {1} /Hello/#yb
console.log('Hello');
```
	

will render into

			console.log('Hello');
	
hello.ts
			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 ++]
}
```
	
			```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 ++]
}
	
code-diff.js
			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

Math Blocks

  • 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
    	
    			<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

      • $\nabla \cdot \mathbf{E} = \frac{\rho}{\varepsilon_0}$

        this is an example of inline equation
      • $$\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 $
    • 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
    	
    			- 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
    	
    			- <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)
    ```
    	
    math.md
    			```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
    ×B=μ0(J+ε0Et) abla imes mathbf{B} = mu_0 left(mathbf{J} + arepsilon_0 rac{partial mathbf{E}}{partial t} ight)

    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)$$
    	
    inline-math.md
    			$$\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: ×B=μ0(J+ε0Et)\nabla \times mathbf{B} = mu_0 left(mathbf{J} + arepsilon_0 rac{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.

Blog Comments

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 =
	
			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.

Projects

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']
    }
];
	
src/lib/projects.ts
			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

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: []
};
	
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.

Prabhu Kiran Konda | © 2024

Made with

svelte-logo