Personal portfolio and blog built with vanilla JavaScript, HTML, and CSS. It’s a single‑page app using hash‑based routing (#/home, #/blog, #/blog/{id}, #/contact).
- Responsive layout: Mobile‑first, modern styling
- Dark/Light theme: Auto theme based on time of day + manual toggle with persistence
- Client‑side routing: Home, Blog, Blog Post, Contact
- Blog system:
- Markdown posts in
data/posts/*.mdwith frontmatter - Index in
data/posts/index.json - Search, tag filtering, pagination, and “Latest posts” on Home
- Syntax highlighting via PrismJS (light/dark themes switch with site theme)
- Markdown posts in
- Contact form: Client‑side validation and simulated submission (no backend)
- Icons: [Lucide] icons via
vendor/lucide.jsusingdata-lucideattributes
- Frontend: Vanilla JavaScript (ES6+)
- Styling: CSS (CSS variables, Flexbox, Grid) in
css/app.css - Syntax highlighting: PrismJS via CDN
- Icons: Lucide via local
vendor/lucide.js - Build tooling: None required (static site)
personal-website/
├── index.html
├── css/
│ └── app.css
├── js/
│ ├── app.js # Main application (routing, rendering, state)
│ ├── config.js # Centralized configuration/constants
│ └── utils.js # Utilities (frontmatter parsing, markdown, helpers)
├── data/
│ └── posts/
│ ├── index.json # List of posts and metadata
│ └── *.md # Markdown posts with frontmatter
├── assets/
│ ├── favicon.ico
│ └── me.jpeg
├── vendor/
│ └── lucide.js # Lucide icon library (local)
├── .nojekyll # For GitHub Pages (disable Jekyll)
├── package.json
└── README.md
#/home— Home#/blog— Blog listing (search, tag filter, pagination)#/blog/{id}— Blog post detail (renders markdown → HTML)#/contact— Contact form (client‑side only, simulated submit)
- Add a markdown file under
data/posts/(e.g.,my-post.md). Start with frontmatter:
---
id: my-post
title: My Post Title
author: Emin Yorgun
tags: [JavaScript, Portfolio]
excerpt: Optional short summary
cover: Optional path/to/image
coverAlt: Optional accessible alt text
---
Your markdown content here...- Add/verify an entry in
data/posts/index.jsonpointing to the file. Frontmatter values overrideindex.jsonwhen both are present.
js/config.jscontains:- Theme: keys and night hours for auto dark mode
- Layout: constants used by the UI
- Routes: route names used by the router
- Blog: posts per page, excerpt length, latest posts count
- Contact/Social links: update
CONFIG.CONTACT_INFOandCONFIG.SOCIAL_LINKSas needed
- Any modern browser
- Optional: a simple HTTP server for local development
Option 1 — open the file directly:
- Open
index.htmlin your browser
Option 2 — use a local server (recommended):
# Python 3
python -m http.server 8000
# Node (if installed)
npx http-server . -p 8000The site will be available at http://localhost:8000.
npm run dev # Starts a simple Python HTTP server on port 8000
npm start # Prints instructions (no build required)
npm run build # Placeholder (no bundling/minification by default)This is a static site. Deploy by uploading the repository contents to any static host (e.g., GitHub Pages, Netlify, Vercel, S3). If you use Cloudflare Web Analytics, replace the token in index.html (data-cf-beacon).
- PrismJS styles are loaded from CDN and switch based on the active theme.
- In development,
index.htmlclears service workers and caches to avoid stale assets. - Icons are instantiated via
window.lucide.createIcons()anddata-lucideattributes.