Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 54 additions & 52 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
<!-- Logo -->
<h1 align="center">
<img src="https://github.com/willtheorangeguy/willtheorangeguy.github.io/blob/main/docs/images/logo.png" height="250px" width="400px" alt="willtheorangeguy.github.io">
<img src="https://raw.githubusercontent.com/willtheorangeguy/.github/main/icons/willtheorangeguy.github.io/logo.png" height="250px" width="400px" alt="willtheorangeguy.github.io">
</h1>

<!-- Copy -->
<h4 align="center">My personal Astro + Astro Paper + Tailwind + Github Pages site.</h4>
<h4 align="center">My personal site: an Astro + AstroPaper + Tailwind blog and portfolio, deployed to GitHub Pages.</h4>

<!-- Badges -->
<div align="center">
<!-- Stability -->
<img alt="Docker State" src="https://github.com/willtheorangeguy/willtheorangeguy.github.io/actions/workflows/docker-image.yml/badge.svg">
<!-- Stability -->
<!-- Astro -->
<img alt="Astro Build State" src="https://github.com/willtheorangeguy/willtheorangeguy.github.io/actions/workflows/astro.yml/badge.svg">
<!-- Docker -->
<img alt="Docker State" src="https://github.com/willtheorangeguy/willtheorangeguy.github.io/actions/workflows/docker-image.yml/badge.svg">
<!-- CodeQL -->
<img alt="CodeQL State" src="https://github.com/willtheorangeguy/willtheorangeguy.github.io/actions/workflows/codeql.yml/badge.svg">
<!-- Gitleaks -->
Expand All @@ -22,75 +22,83 @@
<img alt="GitHub Issues" src="https://img.shields.io/github/issues/willtheorangeguy/willtheorangeguy.github.io">
<!-- Pull Requests -->
<img alt="GitHub Pull Requests" src="https://img.shields.io/github/issues-pr/willtheorangeguy/willtheorangeguy.github.io">
<!-- Discord -->
<img alt="Discord Server ID" src="https://img.shields.io/discord/956764342618030081">
<!-- Language Count -->
<img alt="GitHub Languages" src="https://img.shields.io/github/languages/count/willtheorangeguy/willtheorangeguy.github.io">
<!-- License -->
<img alt="License" src="https://img.shields.io/github/license/willtheorangeguy/willtheorangeguy.github.io">
</div>

<!-- Navigation -->
<p align="center">
<a href="#key-features">Key Features</a> •
<a href="#how-to-use">How To Use</a> •
<a href="#installation">Installation</a> •
<a href="#usage">Usage</a> •
<a href="#documentation">Documentation</a> •
<a href="#support">Support</a> •
<a href="#contributing">Contributing</a> •
<a href="#changelog">Changelog</a> •
<a href="#credits">Credits & Contributors</a>
<a href="#credits">Credits</a> •
<a href="#license">License</a>
</p>

<!-- Screenshot(s) -->
<!-- Screenshot -->

![screenshot](./docs/images/welcome.jpg)
![screenshot](https://raw.githubusercontent.com/willtheorangeguy/.github/main/icons/willtheorangeguy.github.io/welcome.jpg)

**The live site is at [williamvdg.me](https://williamvdg.me).**

## Key Features

- Uses the Astro build system to create a static blog.
- Stylized with Tailwind CSS and the Astro Paper theme.
- Projects, Labs, and Uses pages.
- Displays links to all of my personal projects.
- Cross platform, web browser based.
- A static Astro 7 blog on the AstroPaper theme, styled with Tailwind 4.
- Posts are Markdown with a Zod-validated schema, so a typo in frontmatter fails the build rather than publishing quietly.
- Per-post social preview images generated at build time with Satori.
- Client-side search over the whole site via Pagefind — no search backend.
- Projects, Labs, and Uses pages, plus a published Storybook style guide at `/styleguide`.
- Short-link redirects under `/r/`, and Google Maps contribution stats refreshed on a schedule.
- Deployed to GitHub Pages and mirrored as a Docker image on every push to `main`.

## Installation

## How To Use
```bash
git clone https://github.com/willtheorangeguy/willtheorangeguy.github.io.git
cd willtheorangeguy.github.io
npm install
npm run dev
```

**To access the latest version of the website visit it at [williamvdg.me](https://willtheorangeguy.github.io/).**
Then open `http://localhost:4321` — http, not https. Either npm or pnpm works locally; CI uses pnpm. Docker and production builds are covered in [`docs/installation.md`](docs/installation.md).

**To clone and run your own copy of this website**, you'll need [Git](https://git-scm.com/downloads) installed on your computer. If you would rather not use Git, you can just download the code from GitHub [above](https://github.com/willtheorangeguy/willtheorangeguy.github.io/archive/refs/heads/main.zip). From your command line:
## Usage

```bash
# Clone this repository
$ git clone https://github.com/willtheorangeguy/willtheorangeguy.github.io.git
Posts are Markdown files in `src/data/blog/`:

# Go into the repository
$ cd willtheorangeguy.github.io
```markdown
---
title: A title
pubDatetime: 2026-08-19T10:00:00Z
description: One sentence, used for previews and the generated OG image.
---

# Run Astro
$ npm run dev
Body copy.
```

You can also pull the [Docker](https://www.docker.com/) image from GitHub Packages. From your command line:

```bash
# Pull image
$ docker pull ghcr.io/willtheorangeguy/willtheorangeguy.github.io:main
`title`, `pubDatetime`, and `description` are required; `tags`, `draft`, `featured`, and the rest are optional and documented in [`docs/usage.md`](docs/usage.md).

# Run container
$ docker run -d -p 8000:80 ghcr.io/willtheorangeguy/willtheorangeguy.github.io:main
Search is powered by Pagefind, which indexes built output — it works after `npm run build && npm run preview`, not under `npm run dev`.

# Now, navigate to localhost in your browser to see the webpage
```
## Documentation

If support is required, please open a **[GitHub Discussion](https://github.com/willtheorangeguy/willtheorangeguy.github.io/discussions/new)** or join our **[Discord](https://discord.gg/axMJXSRvTJ)**.
Full documentation lives in [`docs/`](docs/README.md):
[Installation](docs/installation.md) · [Quickstart](docs/quickstart.md) · [Usage](docs/usage.md) · [Configuration](docs/configuration.md) · [Architecture](docs/architecture.md) · [Development](docs/development.md) · [Deployment](docs/deployment.md) · [Google Maps automation](docs/google-maps-automation.md) · [FAQ](docs/faq.md) · [Troubleshooting](docs/troubleshooting.md) · [Roadmap](docs/roadmap.md)

## Contributing
Legal text served by the site lives in [`docs/legal/`](docs/legal/): [Privacy Policy](docs/legal/privacy.md) and [Terms and Conditions](docs/legal/terms.md).

Please contribute using [GitHub Flow](https://guides.github.com/introduction/flow). Create a branch, add commits, and [open a pull request](https://github.com/willtheorangeguy/willtheorangeguy.github.io/compare).
![Visualization of the codebase](./diagram.svg)

Please read [`CONTRIBUTING`](https://github.com/willtheorangeguy/.github/blob/main/CONTRIBUTING.md) for details on our [`CODE OF CONDUCT`](https://github.com/willtheorangeguy/.github/blob/main/CODE_OF_CONDUCT.md), and the process for submitting pull requests to us.
## Support

## Changelog
Open a [GitHub Discussion](https://github.com/willtheorangeguy/willtheorangeguy.github.io/discussions/new) or file an [issue](https://github.com/willtheorangeguy/willtheorangeguy.github.io/issues/new/choose).

See the [`CHANGELOG`](CHANGELOG.md) file for details.
## Contributing

![Visualization of the codebase](./diagram.svg)
Contributions welcome. See the org-wide [Contributing Guide](https://github.com/willtheorangeguy/.github/blob/main/CONTRIBUTING.md) and [Code of Conduct](https://github.com/willtheorangeguy/.github/blob/main/CODE_OF_CONDUCT.md).

## Credits

Expand Down Expand Up @@ -126,12 +134,6 @@ This software uses the following open source packages, projects, services or web
- [@willtheorangeguy](https://github.com/willtheorangeguy) - Sponsor on [PayPal](https://paypal.me/wvdg44?country.x=CA&locale.x=en_US)
- [@JASKIRAT11011](https://github.com/JASKIRAT11011)

## You may also like...

- [Running Calculator](https://github.com/willtheorangeguy/Running-Calculator) - A running speed calculator for any unit of distance.
- [Python Logo Widgets](https://github.com/willtheorangeguy/Python-Logo-Widgets) - Python Powered Logo widgets that can be added to any GUI project.
- [Random Lotto Number Chooser](https://github.com/willtheorangeguy/Random-Lotto-Number-Chooser) - Randomly pick lucky lotto numbers.

## License

This project is licensed under the [MIT License](https://mit-license.org/) - see the [`LICENSE`](LICENSE.md) file for details. See the [Privacy Policy](https://github.com/willtheorangeguy/willtheorangeguy.github.io/blob/main/docs/legal/PRIVACY.md) and [Terms and Conditions](https://github.com/willtheorangeguy/willtheorangeguy.github.io/blob/main/docs/legal/TERMS.md) for legal information.
This project is licensed under the [MIT License](https://mit-license.org/) - see the [`LICENSE`](LICENSE.md) file for details. See the [Privacy Policy](docs/legal/privacy.md) and [Terms and Conditions](docs/legal/terms.md) for legal information.
51 changes: 39 additions & 12 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,40 @@
# willtheorangeguy.github.io Documentation

This folder includes all of the docs for willtheorangeguy.github.io.

```text
├── docs
| ├── images
| ├── legal
| | ├── PRIVACY.md
| | ├── TERMS.md
| ├── USAGE.md
└── README.md
# willtheorangeguy.github.io — Documentation

The source of my personal site at [williamvdg.me](https://williamvdg.me): an Astro static site
built on the AstroPaper theme, deployed to GitHub Pages and mirrored as a Docker image.

```
docs/
├── README.md this index
├── quickstart.md clone to a running dev server
├── installation.md prerequisites, npm and pnpm, Docker
├── usage.md writing posts, drafts, and the short-link redirects
├── configuration.md site metadata, socials, feature flags, timezone
├── architecture.md Astro layout, React islands, OG images, search, theming
├── development.md lint, format, Storybook, conventions, CI
├── deployment.md Pages, the custom domain, the Docker image
├── google-maps-automation.md the scheduled contribution-stats scraper
├── faq.md questions this setup raises
├── troubleshooting.md concrete errors and their causes
├── roadmap.md gaps and deliberate non-goals
├── legal/
│ ├── privacy.md privacy policy served by the site
│ └── terms.md terms and conditions served by the site
└── internal/
└── known-issues.md defects found while documenting (not fixed)
```

## Start here

- Running it locally — [Quickstart](./quickstart.md)
- Writing a post — [Usage](./usage.md)
- Changing the site's identity, socials, or feature flags — [Configuration](./configuration.md)
- Understanding the build — [Architecture](./architecture.md), then [Deployment](./deployment.md)

## Note on the Projects page

`src/pages/projects.astro` hardcodes image URLs pointing into other repositories'
`docs/images/` directories. Those directories are being removed across the account in favour of
a central `willtheorangeguy/.github/icons/`, so most of those images will 404 as that work
merges. This is recorded in [`internal/known-issues.md`](./internal/known-issues.md) with the
replacement URLs.
18 changes: 0 additions & 18 deletions docs/USAGE.md

This file was deleted.

94 changes: 94 additions & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# willtheorangeguy.github.io — Architecture

An Astro static site on the [AstroPaper](https://github.com/satnaing/astro-paper) theme. Astro 7,
Tailwind 4, React 19 for a few interactive islands, TypeScript throughout. Output is static HTML
— there is no server.

## Layout

```
src/
├── config.ts site metadata, pagination, feature flags, timezone
├── constants.ts SOCIALS, SHARE_LINKS, GISCUS
├── content.config.ts Zod schema for the blog collection
├── data/blog/ posts, as Markdown
├── pages/ routes, including projects.astro and og.png.ts
├── layouts/ page shells
├── components/ .astro components, plus three .tsx islands
├── stories/ Storybook stories
├── styles/global.css theme variables via @theme inline
├── utils/ OG generation, caches, helpers
└── assets/icons/ SVGs imported by constants.ts

public/
├── r/ short-link redirects, with an index
├── toggle-theme.js the theme switcher, vanilla JS
├── pagefind/ search index, copied in by the build
└── styleguide/ Storybook output, built by the build
```

`@/` resolves to `src/`, configured in `tsconfig.json`. Relative imports that climb out of a
directory are avoided.

## Content

Posts are a Zod-validated Astro content collection. The schema is the contract: it names every
legal frontmatter field, and anything else fails the build. Files prefixed `_` are skipped by
the loader.

## React islands, kept small

Only three components are React, and only because they are interactive: `GoogleMapsStats.tsx`,
`UnsplashStats.tsx`, and `Comments.tsx` (Giscus). Everything else is `.astro` and ships no
JavaScript. That boundary is worth keeping — the reason the site is fast is that almost none of
it hydrates.

## OG images

Generated at build time with Satori and `@resvg/resvg-js`. `src/pages/og.png.ts` is the entry
point, templates are in `src/utils/og-templates/`, and orchestration is in
`src/utils/generateOgImages.ts`. `@resvg/resvg-js` is excluded from Vite's `optimizeDeps`
because it is a native module, which is the sort of thing that looks like a stray config line
until you remove it.

## Search

[Pagefind](https://pagefind.app/), which indexes built output rather than source. The build runs
`pagefind --site dist` and copies the result into `public/pagefind/` so `astro preview` can serve
it. Search therefore does not work under `npm run dev`, and a partial build leaves `/search`
broken — which is why the build script is longer than `astro build`.

## Theming

Light and dark are CSS variables in `src/styles/global.css`, declared with `@theme inline`:
`--color-accent`, `--color-background`, `--color-foreground`, `--color-border`, `--color-muted`.
The toggle is `public/toggle-theme.js`, plain JavaScript with no framework, so the theme applies
before hydration and the page does not flash.

## The build pipeline

```
npm run build
= fetch-maps-stats # scrape/refresh Google Maps contribution stats
&& storybook:build # Storybook -> public/styleguide
&& astro check # type-check
&& astro build # -> dist/
&& pagefind --site dist # search index
&& cp -r dist/pagefind public/
```

Each step leaves something visibly missing if skipped. The Storybook step means a normal build
also publishes the style guide at `/styleguide`.

## Deployment

Two targets from the same source: GitHub Pages on push to `main`, and a Docker image (Node build
stage, Nginx serving stage) published to GHCR. [Deployment](./deployment.md) covers both.

## The Projects page

`src/pages/projects.astro` is a hand-maintained list of projects with a hardcoded image URL each.
Those URLs point into other repositories' `docs/images/` directories, which are being retired
across the account in favour of `willtheorangeguy/.github/icons/`. Most of them will 404 as that
work lands — see [`internal/known-issues.md`](./internal/known-issues.md), which lists the
replacement URLs.
58 changes: 58 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# willtheorangeguy.github.io — Configuration

Four files decide almost everything. None of them needs environment variables — the site is
static and builds the same way everywhere.

## `src/config.ts` — site identity and behaviour

The single source of truth for site metadata.

| Key | Current | Effect |
|---|---|---|
| `website` | `https://williamvdg.me/` | Canonical URL. Feeds sitemap, RSS, and canonical tags. |
| `author`, `profile` | `willtheorangeguy` | Author name and profile link |
| `title`, `desc` | "To Be Continued" | Site title and description |
| `ogImage` | `hero.jpg` | Fallback social preview image |
| `lightAndDarkMode` | `true` | Whether the theme toggle appears |
| `postPerIndex` | `5` | Posts on the home page |
| `postPerPage` | `10` | Posts per page in listings |
| `scheduledPostMargin` | 15 minutes | Grace window for posts dated slightly in the future |
| `showArchives` | `true` | The archive page |
| `showBackButton` | `true` | Back button on post pages |
| `editPost` | enabled | The "Suggest Changes" link and the branch it edits |
| `dynamicOgImage` | `true` | Generate per-post OG images at build time |
| `lang` | `en` | `html lang` attribute |
| `timezone` | `America/Vancouver` | Default for post dates; a post may override it in frontmatter |

## `src/constants.ts` — links

`SOCIALS` is the icon row: GitHub, Instagram, LinkedIn, X, Mastodon, Bluesky, Stack Overflow,
YouTube, Steam, and email. Each entry is a name, an href, a link title for screen readers, and an
imported SVG. Adding one means adding the icon to `src/assets/icons/` and importing it here.

`SHARE_LINKS` is the per-post share row. `GISCUS` configures the comment system, which is backed
by GitHub Discussions on this repository — the ids there come from the Giscus setup page and are
public by design.

## `src/content.config.ts` — what a post may contain

A Zod schema for the `blog` collection. It defines every valid frontmatter field and rejects
anything else at build time, so a typo in a key fails the build rather than being silently
ignored. [Usage](./usage.md) lists the fields.

## `astro.config.ts` — the build

Integrations (sitemap, React), Shiki syntax-highlighting themes, and remark plugins. `site` is
read from `SITE.website` rather than duplicated.

## The custom domain

`CNAME` contains `williamvdg.me`. It is what makes GitHub Pages serve the site from that domain
rather than `willtheorangeguy.github.io`, and it must stay in the published output — see
[Deployment](./deployment.md).

## Google Maps stats

The one piece of data fetched from outside. It is cached into `src/data/google-maps-stats.json`
and `src/utils/googleMapsCache.ts`, refreshed on a schedule, and documented in
[Google Maps automation](./google-maps-automation.md).
Loading
Loading