Skip to content

bitterteriyaki/portfolio

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

154 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🌐 kyomi.dev

Personal portfolio and engineering blog, built with Nuxt 4, Nuxt UI, and TailwindCSS.

Nuxt Nuxt UI TypeScript Tailwind CSS pnpm


✨ Features

  • Portfolio: hero section, about me, and an experience timeline with technology badges
  • Blog: Markdown-powered posts with KaTeX math rendering, syntax highlighting, and estimated reading time
  • Dark mode: seamless theme toggle with Nuxt UI
  • Fully static: prerendered at build time via Nitro's crawl-links strategy
  • SEO-ready: per-page meta tags populated from post frontmatter
  • Accessible: built with @nuxt/a11y and semantic HTML throughout
  • Testing: three-tier test suite: Vitest unit, Vitest component (Nuxt + happy-dom), and Playwright E2E

πŸ› οΈ Tech Stack

Layer Technology
Framework Nuxt 4
Component library Nuxt UI v4
Styling Tailwind CSS v4
Language TypeScript 5.9
Content / CMS @nuxt/content v3 (Markdown)
Math rendering KaTeX (remark-math + rehype-katex)
Icons Iconify (heroicons, lucide, mdi, ri, simple-icons)
Images @nuxt/image
Unit / component tests Vitest 4 + @nuxt/test-utils + happy-dom
E2E tests Playwright
Linting ESLint with @nuxt/eslint-config (stylistic)
Package manager pnpm 10.32
Runtime Node 24.14 (pinned via mise.toml)

πŸ—‚οΈ Project Structure

.
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ assets/css/main.css        # Global styles, fonts, KaTeX overrides
β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”œβ”€β”€ content/               # Prose overrides for Nuxt Content
β”‚   β”‚   β”œβ”€β”€ landing/               # Home page sections (Hero, AboutMe, Experiences, LatestPosts)
β”‚   β”‚   β”œβ”€β”€ layout/                # Shell components (AppHeader, AppFooter, AppMain)
β”‚   β”‚   └── overlays/blog/         # Blog post components (PostContent, PostInfo, PostTags…)
β”‚   β”œβ”€β”€ pages/
β”‚   β”‚   β”œβ”€β”€ index.vue              # Landing page (/)
β”‚   β”‚   └── blog/
β”‚   β”‚       β”œβ”€β”€ index.vue          # Blog listing (/blog)
β”‚   β”‚       └── [...slug].vue      # Individual post (/blog/...)
β”‚   β”œβ”€β”€ app.config.ts              # Nuxt UI theme (primary: blue, neutral: slate)
β”‚   β”œβ”€β”€ app.vue                    # Root component
β”‚   └── error.vue                  # Custom error page
β”œβ”€β”€ content/
β”‚   └── blog/
β”‚       β”œβ”€β”€ 2025/                  # Posts from 2025
β”‚       └── 2026/                  # Posts from 2026
β”œβ”€β”€ tests/
β”‚   β”œβ”€β”€ e2e/                       # Playwright E2E specs
β”‚   β”œβ”€β”€ nuxt/                      # Vitest component tests
β”‚   └── unit/                      # Vitest unit tests
β”œβ”€β”€ content.config.ts              # Blog collection schema (Zod)
β”œβ”€β”€ nuxt.config.ts                 # Main Nuxt configuration
β”œβ”€β”€ eslint.config.mjs              # ESLint rules
β”œβ”€β”€ vitest.config.ts
β”œβ”€β”€ playwright.config.ts
└── mise.toml                      # Node + pnpm version pins

πŸš€ Getting Started

πŸ“‹ Prerequisites

Use mise install to set up the correct Node and pnpm versions based on mise.toml.

πŸ“¦ Installation

pnpm install

πŸ§ͺ Development

Start the dev server on http://localhost:3000:

pnpm dev

πŸ—οΈ Build

# Production build
pnpm build

# Preview the production build locally
pnpm preview

🧾 Available Scripts

Script Description
pnpm dev Start the development server
pnpm build Build for production
pnpm preview Preview the production build
pnpm lint Run ESLint
pnpm lint:fix Run ESLint and auto-fix issues
pnpm typecheck Run TypeScript type checking
pnpm test Run all Vitest tests
pnpm test:watch Run Vitest in watch mode
pnpm test:coverage Run Vitest with coverage report
pnpm test:unit Run unit tests only
pnpm test:nuxt Run component tests only
pnpm test:e2e Run Playwright E2E tests
pnpm test:e2e:ui Run Playwright E2E tests with the UI runner

✍️ Writing Blog Posts

Posts live in content/blog/<year>/ as Markdown files. The filename prefix (e.g. 1.) controls ordering within a year.

Each file must include the following frontmatter:

---
date: 2025-03-10
minRead: 8
image: /path/to/cover-image.png
author:
  name: kyomi
  description: software engineer
  avatar:
    src: /github/bitterteriyaki.png
    alt: kyomi's avatar
tags:
  - algorithms
  - math
---

KaTeX math is supported inline ($...$) and in display blocks ($$...$$). Code blocks support syntax highlighting for most languages

πŸ“ Code Conventions

This project enforces strict code style via ESLint:

  • Imports must be alphabetically sorted
  • Vue SFCs must follow the block order: <script> β†’ <template> β†’ <style>
  • Max line length in templates: 80 characters
  • Up to 5 attributes per line in Vue templates

Run pnpm lint:fix to auto-fix most issues before committing.

πŸ“„ License

This project is licensed under the MIT License. See LICENSE for the full text.

πŸ“« Contact

About

πŸ’Ό My personal portfolio.

Topics

Resources

License

Stars

Watchers

Forks

Contributors

Languages