Skip to content

Latest commit

Β 

History

128 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Alex van Wolferen's Blog

Just another blog about Sitecore, tips and tricks

A modern, high-performance blog built with Next.js 16, React 19, TypeScript, and Tailwind CSS. This blog focuses on Sitecore architecture, development tips, Azure, and web technologies.

Node.js Version Next.js React TypeScript License: MIT

πŸš€ Features

  • Modern Tech Stack: Built with Next.js 16 (App Router), React 19, and TypeScript 6.0
  • Markdown-Based Content: Write blog posts in Markdown with frontmatter metadata
  • Theme Support: Light, dark, and christmas theme switching with system preference detection
  • Optimized Images: Next.js Image optimization with AVIF and WebP support
  • Responsive Design: Mobile-first design with Tailwind CSS and responsive typography
  • Reading Progress Bar: Visual indicator of reading progress on blog posts
  • Infinite Scroll: Smooth infinite scrolling for browsing posts
  • Auto-Scroll Navigation: Automatic scroll to next post functionality
  • Tag & Category System: Organize and filter posts by tags and categories
  • Archive View: Browse posts chronologically
  • SEO Optimized: Built-in metadata, Open Graph, and Twitter Card support
  • Google Analytics: Integrated analytics tracking
  • Comprehensive Testing: E2E testing with Playwright and anti-flakiness patterns

πŸ“‹ Prerequisites

  • Node.js: >= 24.0.0
  • pnpm: 12.4.1 (installed through Corepack)

πŸ› οΈ Installation

  1. Clone the repository:
git clone https://github.com/avwolferen/blog.git
cd blog
  1. Enable Corepack, which manages the pnpm version used by this project:
corepack enable
corepack install
  1. Verify that pnpm is available:
pnpm --version
  1. Install dependencies:
pnpm install

☁️ GitHub Codespaces

This repository is configured for GitHub Codespaces, providing a complete development environment in the cloud.

Open in GitHub Codespaces

Quick Start with Codespaces

  1. Click the "Open in GitHub Codespaces" badge above or create a new codespace from the repository
  2. Wait for the environment to build (first time setup takes ~2-3 minutes)
  3. Once ready, the dependencies are automatically installed
  4. Start developing immediately with pnpm dev

What's Included

  • Node.js 24 with TypeScript support
  • Pre-installed VS Code extensions for Next.js, React, Tailwind CSS, and Playwright
  • Playwright browsers automatically installed and configured
  • Port forwarding for the Next.js dev server (port 3000)
  • GitHub CLI for repository management
  • Docker support for containerized workflows

All configurations are in .devcontainer/ directory.

πŸƒβ€β™‚οΈ Running the Application

Development Mode

Start the development server with Turbopack (faster):

pnpm dev

Or use Webpack:

pnpm dev:webpack

Open http://localhost:3000 to view the blog.

Production Build

pnpm build
pnpm start

Type Checking

pnpm type-check

Linting

pnpm lint

Image Validation

pnpm check-images

Checks every blog post for broken local image references and disallowed external image URLs.

πŸ” Security Headers

The application sets strict response headers in next.config.js for all routes:

  • Content-Security-Policy
  • X-Frame-Options: DENY
  • Referrer-Policy: strict-origin-when-cross-origin
  • Permissions-Policy with powerful features disabled (e.g. camera=(), microphone=(), geolocation=(), payment=(), publickey-credentials-get=()).

For this static blog, these features are not required, so disabling them reduces attack surface and limits unnecessary browser capability exposure. If future functionality needs one of these APIs (e.g. embedded capture tools or passkeys), explicitly update the header and tests together.

πŸ§ͺ Testing

This project uses Playwright for end-to-end testing with comprehensive anti-flakiness patterns.

Run All Tests

pnpm test

Run Tests with UI Mode

pnpm test:ui

Run Tests in Specific Browser

pnpm test:chromium
pnpm test:firefox
pnpm test:webkit

Run Mobile Tests

pnpm test:mobile

Run Tests with Retries (CI-like)

pnpm test:stable

Additional Testing Resources

πŸ“ Project Structure

blog/
β”œβ”€β”€ .devcontainer/           # GitHub Codespaces configuration
β”œβ”€β”€ .github/                 # GitHub Actions and workflows
β”œβ”€β”€ app/                     # Next.js App Router pages
β”‚   β”œβ”€β”€ page.tsx            # Homepage with featured posts
β”‚   β”œβ”€β”€ layout.tsx          # Root layout with metadata
β”‚   β”œβ”€β”€ globals.css         # Global styles
β”‚   β”œβ”€β”€ api/                # API routes (content endpoint)
β”‚   β”œβ”€β”€ archive/            # Archive page for all posts
β”‚   β”œβ”€β”€ blog/[slug]/        # Dynamic blog post pages
β”‚   β”œβ”€β”€ content/[...path]/  # Dynamic content pages
β”‚   β”œβ”€β”€ tags/               # Tag listing and filtering
β”‚   └── not-found.tsx       # 404 page
β”œβ”€β”€ components/             # React components
β”‚   β”œβ”€β”€ Header.tsx          # Site header with navigation
β”‚   β”œβ”€β”€ Footer.tsx          # Site footer
β”‚   β”œβ”€β”€ ThemeProvider.tsx   # Light/dark/christmas theme provider
β”‚   β”œβ”€β”€ GoogleAnalytics.tsx # Analytics component
β”‚   β”œβ”€β”€ ReadingProgressBar.tsx  # Reading progress indicator
β”‚   β”œβ”€β”€ InfiniteScrollBlog.tsx  # Infinite scroll component
β”‚   └── AutoScrollNext.tsx  # Auto-scroll navigation
β”œβ”€β”€ content/                # Blog content (Markdown files)
β”‚   β”œβ”€β”€ blog/               # Individual blog posts
β”‚   β”‚   └── [post-slug]/
β”‚   β”‚       β”œβ”€β”€ index.md    # Post content with frontmatter
β”‚   β”‚       └── *.png/jpg   # Post images
β”‚   └── assets/             # Shared assets
β”œβ”€β”€ lib/                    # Utility functions
β”‚   └── markdown.ts         # Markdown processing utilities
β”œβ”€β”€ types/                  # TypeScript type definitions
β”‚   └── blog.ts             # Blog post types
β”œβ”€β”€ tests/                  # Playwright E2E tests
β”‚   β”œβ”€β”€ e2e/                # End-to-end test files
β”‚   β”œβ”€β”€ helpers/            # Test helper utilities
β”‚   └── *.md                # Testing documentation
β”œβ”€β”€ public/                 # Static assets
β”‚   └── robots.txt          # SEO robots file
β”œβ”€β”€ next.config.js          # Next.js configuration
β”œβ”€β”€ tailwind.config.ts      # Tailwind CSS configuration
β”œβ”€β”€ tsconfig.json           # TypeScript configuration
β”œβ”€β”€ playwright.config.ts    # Playwright test configuration
└── eslint.config.mjs       # ESLint configuration (flat config)

✍️ Creating a Blog Post

  1. Create a new folder in content/blog/ with your post slug:
mkdir content/blog/my-new-post
  1. Create an index.md file with frontmatter:
---
title: "My New Post Title"
date: "2026-01-19"
categories: ["Sitecore", "Development"]
tags: ["next.js", "typescript", "tutorial"]
img: ./cover.jpg
---

Your post content goes here...
  1. Add images to the same folder and reference them in your markdown:
![Alt text](./image.png)

Frontmatter Fields

  • title (required): Post title
  • date (required): Publication date in YYYY-MM-DD format
  • categories (required): Array of category names
  • tags (optional): Array of tag names for filtering
  • img (optional): Path to cover image (relative to post folder)

🎨 Customization

Theme Colors

Edit tailwind.config.ts to customize the color scheme. The blog includes light, dark, and christmas themes with custom color definitions.

Site Metadata

Update metadata in app/layout.tsx:

export const metadata: Metadata = {
  title: 'Your Blog Title',
  description: 'Your description',
  // ...
}

Google Analytics

Configure Google Analytics by setting the tracking ID in the GoogleAnalytics component in components/GoogleAnalytics.tsx. Analytics loading is gated by explicit user consent via components/AnalyticsConsent.tsx.

Content Security Policy (script-src) note

script-src currently keeps 'unsafe-inline'.

We tested removing 'unsafe-inline' and observed breakage:

  • browser CSP errors for blocked inline scripts (Executing inline script violates ... script-src)
  • runtime/hydration failures (for example: Expected a request ID to be defined for the document via self.__next_r)
  • consent banner interaction tests failing as a side effect of blocked runtime scripts

For now, 'unsafe-inline' is retained for compatibility with Next.js App Router runtime scripts. A stronger follow-up mitigation is to migrate to a nonce-based CSP (and pass nonces to all framework and analytics scripts) so script-src can be tightened without breaking functionality.

🧰 Technologies Used

Core Framework

Styling & UI

Content Processing

  • gray-matter - Parse frontmatter from Markdown files
  • marked - Fast Markdown parser and compiler
  • Prism.js - Lightweight syntax highlighting

Utilities

  • date-fns - Modern JavaScript date utility library
  • Sharp - High-performance image processing

Testing

Development Tools

πŸ‘€ Author

Alex van Wolferen

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

🀝 Contributing

Contributions, issues, and feature requests are welcome! Feel free to check the issues page.


Note: This blog focuses on Sitecore architecture, Azure development, and modern web technologies. Content reflects personal experiences and technical insights from a Sitecore MVP.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages