Updated: 2 years ago

How I Made This Blog

💭 Blogging...

I started my first blog at 12 using Blogfa and some simple HTML-JS tricks to engage my classmates, where we collectively shared our favorite songs and videos.

Later, I remained active primarily on Google+, Twitter, and Telegram (Channel). However, WordPress never quite resonated with me. Despite its robust features, something about its multitude of built-in functionalities didn't appeal to me, perhaps because it seemed too automated with an old-fashioned UI.

Upon delving into front-end and back-end libraries, I found myself in need of a straightforward and swift microblogging platform. Managing intricate Django/React dependencies seemed impractical given my time constraints. Thus, I opted for Svelte and QWER. Now, I've decided to venture into the realm of personal blogging, aiming to share my projects and musings with a wider audience. I made this blog in less than 3 days!

In this guide, I'll provide a concise yet comprehensive overview of the process I undertook to bring my personal blog to life.

Svelte + QWER

Download & Installations

In this guide, we'll use VS Code , but you're free to use whatever IDE you like. In VSCode, install this extension for Svelte ; it'll help you write better code and debug more easily.

  1. Download and install NodeJS and pnpm
  2. Open your terminal ( Ctrl + Shift + ` ) and create a new QWER project, then change the directory to it:
npx degit kwchang0831/svelte-QWER MyBlog && cd MyBlog
  1. Install the pnpm package manager:
pnpm i
  1. Set up husky to auto-check pre-commit git hooks:
pnpm husky
  1. Start the local dev server:
pnpm dev

Configs

Changing Pictures

You can change pictures from the paths below, I created a 512×512 PNG logo for myself (you just need a png logo, then you can convert it to ico using online services; this one is good for example):

Picture Path
Profile Picture (Avatar) /user/assets/avatar.png
Logo (PNG) /user/public/favicon.png
Logo (favicon) /user/public/favicon.ico

Change or Disable the 360-Degree Rotation Effect of the Avatar Photo

Search for hover:rotate-[360deg] transition-transform duration-1000 in all files (the main avatar is located in /src/lib/components/image_avatar.svelte ). To change to a simpler rotation, add the following to the <style> section at the end:

.avatar img {
background-color: var(--qwer-bg-color);
}
@keyframes shake {
0%, 100% {
transform: rotate(0deg);
}
25% {
transform: rotate(10deg);
}
75% {
transform: rotate(-10deg);
}
}
.shake-hover:hover {
animation: shake 0.5s ease-in-out;
}

Then change the class of <picture> to:

class={className ??
'rounded-full shadow-xl !w-32 !h-32 aspect-auto object-cover shake-hover'} />

You can change this behavior in more files (default rotation is still available in the following files: /src/lib/components/header.svelte & /src/lib/components/post_heading.svelte ).

To disable this effect, just remove the hover:rotate-[360deg] transition-transform duration-1000 part.

Add More Logos Like LinkedIn

  1. Edit the following file (Site > Author) and add more properties like the github that already exists: /src/lib/types/site.d.ts
  2. Update your added properties inside /user/config/site.ts ( siteConfig )
  3. Edit the following file and add more elements like github : /src/lib/components/index_profile.svelte You can add an icon that is not available inside index_profile.svelte , just go here , choose Svelte and copy the SVG code, then use it like:
<svg
xmlns="http://www.w3.org/2000/svg"
width="1.75rem"
height="1.75rem"
viewBox="0 0 32 32"
fill="currentColor"
aria-hidden="true">
<path
d="M27.71 4.29a1 1 0 0 0-1.05-.23l-22 8a1 1 0 0 0 0 1.87l8.59 3.43L19.59 11L21 12.41l-6.37 6.37l3.44 8.59A1 1 0 0 0 19 28a1 1 0 0 0 .92-.66l8-22a1 1 0 0 0-.21-1.05" />
</svg>

Change bold text color

Navigate to the file /src/lib/styles/defaultTheme.scss and search for:

--qwer-strong-color: green;

Change them to:

--qwer-strong-color: inherit;

Change Header Items (Navigation Items)

Inside /user/config/site.ts search for navConfig & mobilenavConfig and change them.

Enable Giscus

  1. Create a new public repository on your GitHub for commenting using giscus & enable Discussions inside it.
  2. Open https://github.com/apps/giscus & click on Install , then choose your username and choose Only select repositories , then choose the repository you just created.
  3. Go to https://giscus.app & enter your GitHub username/repo_name that you created in step 0 , then choose the configs you prefer. At the end, copy the final script.
  4. Create a .env file inside the root of your QWER directory & paste the necessary data into it:
# data-repo
QWER_GISCUS_REPO=username/reponame
# data-repo-id
QWER_GISCUS_REPO_ID=duywahdUHD_dajkwdn
# data-category
QWER_GISCUS_CATEGORY=Announcements
# data-category-id
QWER_GISCUS_CATEGORY_ID=Dbwhj_DUANiwdni

More configs of giscus: giscusConfig inside /user/config/site.ts .

  1. Inside the path /user/assets/ create a folder ( src_my_certs )
  2. Create a new post ( /user/blogs/certificates ), inside the index.md , add a list of dictionaries like below:
<script>
const images = [
{ src: '/src_my_certs/mycertificate.png', caption: 'Jan 12, 2025 - My Certificate', link: 'https://www.coursera.org/account/accomplishments/verify/sample' },
...
];
function handleImageClick(event) {
event.stopPropagation();
}
</script>
  1. Add styles and main Svelte code:
<style>
.gallery {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.gallery-item {
position: relative;
width: calc(25% - 10px); /* Four columns with 10px gap */
box-sizing: border-box;
}
.image-container {
position: relative;
width: 100%;
}
.gallery-item img {
width: 100%;
height: auto;
display: block;
transition: filter 0.3s ease;
}
.gallery-item:hover img {
filter: blur(5%);
}
.icon-overlay {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
justify-content: center;
align-items: center;
/* Default opacity of icon */
opacity: 0;
transition: opacity 0.3s ease;
pointer-events: none;
}
.gallery-item:hover .icon-overlay {
opacity: 1;
pointer-events: all;
}
.gallery-item:hover .icon-overlay a {
opacity: 0.70; /* Increase opacity of icon on hover */
}
.icon-overlay a {
font-size: 24px;
color: white;
text-decoration: none;
background-color: rgba(0, 0, 0, 0.5);
padding: 10px;
border-radius: 50%;
/* Default opacity of icon link */
opacity: 0.5;
}
.caption {
text-align: center;
margin-top: 5px;
}
@media (max-width: 768px) {
.gallery-item {
width: calc(50% - 10px);
}
}
@media (max-width: 480px) {
.gallery-item {
width: calc(100% - 10px);
}
}
</style>
<div class="gallery">
{#each images as { src, caption, link } (src)}
<div class="gallery-item">
<div class="image-container">
{#if link !== ''}
<button class="icon-overlay"
aria-label="Opens the link to certificate"
on:click|stopPropagation={() => handleImageClick(event)}
on:keypress={(event) => { if(event.key === 'Enter') handleImageClick(event); }}
tabindex="0"
style="all: unset; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">
<a href={link} target="_blank" rel="noopener noreferrer">🔗</a>
</button>
{/if}
<ImgZoom src={src} alt={caption} class="h-full object-cover" />
</div>
<div class="caption">{@html caption}</div>
</div>
{/each}
</div>

Deploying to Vercel

Before doing this you must create a GitHub repository (could be private), then push all your current local project into it. Then, sign up on Vercel and connect your GitHub, choose the repo you want to deploy to Vercel, then choose the root folder. Remember to include .env settings manually as it isn't committed by default.

This post will be updated...!