portfolio-svelte Svelte Themes

Portfolio Svelte

A modern SvelteKit portfolio for Damian Korver. Using Sveltekit, TailwindCSS, and SkeletonUI

Portfolio Website

A modern, performant portfolio website built with SvelteKit 5, TypeScript, and Tailwind CSS v4. Deployed on Cloudflare Pages with integrated R2 storage for automated project screenshots.

โœจ Features

  • ๐ŸŽจ Modern UI - Built with SvelteKit 5 and Tailwind CSS v4
  • ๐ŸŒ“ Dark Mode - Theme switching with persistent preferences
  • ๐Ÿ“ธ Auto Screenshots - Automated project screenshots using Cloudflare Browser Rendering API
  • โšก Edge Deployment - Deployed on Cloudflare Pages for global performance
  • ๐Ÿ”’ UUID-based Security - Secure project identification preventing enumeration
  • ๏ฟฝ๏ธ Rate Limiting - Protection against API abuse and DDoS attacks
  • ๐Ÿ” Security Headers - CSP, HSTS, and other security best practices
  • ๏ฟฝ๐Ÿ“ฑ Responsive Design - Mobile-first design with smooth animations
  • ๐ŸŽญ Iconify Integration - Access to 200,000+ icons via @iconify/svelte
  • ๐Ÿงช E2E Testing - Playwright tests for quality assurance

๐Ÿ› ๏ธ Tech Stack

๐Ÿš€ Getting Started

Prerequisites

  • Node.js 18+
  • pnpm (or npm/yarn)
  • Cloudflare account (for deployment)

Installation

  1. Clone the repository:

    git clone https://github.com/Damianko135/portfolio-svelte.git
    cd portfolio-svelte
    
  2. Install dependencies:

    pnpm install
    
  3. Start the development server:

    pnpm dev
    

The application will be available at http://localhost:5173

๐Ÿ“‹ Managing Projects

Adding a New Project

To add a new project to your portfolio, edit src/lib/data/projects.json and add a new entry:

{
    "id": 4,
    "uuid": "d4e5f6a7-b8c9-0123-def4-567890123456",
    "name": "Your Project Name",
    "url": "https://your-project-url.com",
    "description": "A brief description of your project",
    "technologies": [{ "name": "Technology Name", "icon": "simple-icons:iconname" }]
}

Generating UUIDs

Each project requires a unique UUID for screenshot identification. Here are several ways to generate one:

node -e "console.log(require('crypto').randomUUID())"

Option 2: Using PowerShell (Windows)

[guid]::NewGuid().ToString()

Option 3: Using Online Tools

Visit uuidgenerator.net or uuid.rocks

Option 4: Using VS Code Extension

Install the "UUID Generator" extension and use Ctrl+Shift+P โ†’ "Insert UUID"

Finding Icon Names

Icons are powered by Iconify. To find an icon:

  1. Visit Iconify Icon Sets
  2. Search for your desired icon
  3. Copy the icon name (e.g., simple-icons:svelte, mdi:github)
  4. Use it in the technologies array

Why UUIDs?

UUIDs are used instead of sequential IDs to:

  • Ensure globally unique identifiers
  • Prevent enumeration attacks on the screenshot API
  • Allow flexible project management without ID conflicts
  • Follow industry best practices for resource identification

๐Ÿงฐ Development

Available Scripts

pnpm dev          # Start development server
pnpm build        # Build for production
pnpm preview      # Preview production build locally with Wrangler
pnpm check        # Run TypeScript and Svelte checks
pnpm check:watch  # Run checks in watch mode
pnpm format       # Format code with Prettier
pnpm lint         # Lint code with Prettier
pnpm test         # Run Playwright E2E tests
pnpm test:e2e     # Run Playwright E2E tests
pnpm playwright   # Install Playwright browsers

Project Structure

portfolio-svelte/
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ lib/
โ”‚   โ”‚   โ”œโ”€โ”€ data/
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ projects.json      # Project data
โ”‚   โ”‚   โ”œโ”€โ”€ server/
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ screenshot.ts      # Screenshot generation logic
โ”‚   โ”‚   โ”œโ”€โ”€ Footer.svelte
โ”‚   โ”‚   โ”œโ”€โ”€ Header.svelte
โ”‚   โ”‚   โ”œโ”€โ”€ Icon.svelte
โ”‚   โ”‚   โ”œโ”€โ”€ ThemeToggle.svelte
โ”‚   โ”‚   โ””โ”€โ”€ types.ts               # TypeScript types
โ”‚   โ”œโ”€โ”€ routes/
โ”‚   โ”‚   โ”œโ”€โ”€ about/                 # About page
โ”‚   โ”‚   โ”œโ”€โ”€ contact/               # Contact page
โ”‚   โ”‚   โ”œโ”€โ”€ projects/              # Projects page
โ”‚   โ”‚   โ”œโ”€โ”€ api/screenshot/[slug]/ # Screenshot API endpoint
โ”‚   โ”‚   โ”œโ”€โ”€ +layout.svelte         # Root layout
โ”‚   โ”‚   โ””โ”€โ”€ +page.svelte           # Home page
โ”‚   โ”œโ”€โ”€ app.css                    # Global styles
โ”‚   โ””โ”€โ”€ app.html                   # HTML template
โ”œโ”€โ”€ static/                        # Static assets
โ”œโ”€โ”€ tests/                         # E2E tests
โ”œโ”€โ”€ wrangler.jsonc                 # Cloudflare configuration
โ””โ”€โ”€ package.json

๐ŸŒ Deployment

Cloudflare Pages Setup

  1. Install Wrangler CLI (if not already installed):

    npm install -g wrangler
    
  2. Login to Cloudflare:

    wrangler login
    
  3. Configure R2 Bucket (for screenshots):

    • Create an R2 bucket named screenshots in your Cloudflare dashboard
    • Update wrangler.jsonc with your bucket name if different
  4. Configure Browser Rendering:

    • Enable Browser Rendering in your Cloudflare account
    • Update the browser binding in wrangler.jsonc if needed
  5. Deploy:

    pnpm deploy
    

This will:

  • Run type checking
  • Build the production bundle
  • Deploy to Cloudflare Pages

Environment Variables

The application uses Cloudflare bindings configured in wrangler.jsonc:

  • SCREENSHOTS - R2 bucket for storing project screenshots
  • MYBROWSER - Browser Rendering API binding

๐Ÿ›ก๏ธ Security Features

This application implements multiple layers of security protection:

Rate Limiting

  • General Endpoints: 30 requests per minute per IP
  • API Endpoints: 10 requests per minute per IP
  • Automatic cleanup of rate limit data
  • Returns 429 Too Many Requests when limit exceeded

Security Headers

All responses include comprehensive security headers:

  • Content Security Policy (CSP) - Restricts resource loading
  • X-Frame-Options - Prevents clickjacking attacks
  • X-Content-Type-Options - Prevents MIME sniffing
  • Referrer-Policy - Controls referrer information
  • Permissions-Policy - Restricts browser features
  • HSTS - Forces HTTPS connections (production only)

API Protection

  • UUID-based project identification (prevents enumeration)
  • User agent validation to block suspicious bots
  • Content-Type validation for POST/PUT/DELETE requests
  • IP-based request tracking via Cloudflare headers

Configuration

Rate limiting and security settings can be adjusted in src/hooks.server.ts:

const RATE_LIMIT_WINDOW = 60 * 1000; // 1 minute
const RATE_LIMIT_MAX_REQUESTS = 30; // General endpoints
const RATE_LIMIT_API_MAX_REQUESTS = 10; // API endpoints

Note: For production-scale applications, consider using Cloudflare KV or Durable Objects for distributed rate limiting.

๐ŸŽจ Customization

Theme Colors

Edit the Tailwind configuration in your CSS or Tailwind config to customize the color scheme.

Content

  • About Page: Edit src/routes/about/+page.svelte
  • Contact Page: Edit src/routes/contact/+page.svelte
  • Home Page: Edit src/routes/+page.svelte
  • Projects: Edit src/lib/data/projects.json

๐Ÿงช Testing

Run E2E tests with Playwright:

# Install browsers (first time only)
pnpm playwright

# Run tests
pnpm test

๐Ÿ“ License

This project is private and not licensed for public use.

๐Ÿค Contributing

This is a personal portfolio project. Feel free to fork it for your own use!

๐Ÿ“ง Contact

For any inquiries, please visit the contact page on the live website.


Built with โค๏ธ using SvelteKit and Cloudflare

Top categories

Loading Svelte Themes