diff --git a/docs/superpowers/plans/2026-05-16-dual-domain.md b/docs/superpowers/plans/2026-05-16-dual-domain.md new file mode 100644 index 0000000..d5ff106 --- /dev/null +++ b/docs/superpowers/plans/2026-05-16-dual-domain.md @@ -0,0 +1,113 @@ +# Dual-Domain Support Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Serve the portfolio on both `gabrielkaszewski.dev` and `gabrielkaszewski.pl` with identical content, with `.dev` as the canonical domain for SEO. + +**Architecture:** Two independent changes — Traefik routing config to accept both hostnames, and Next.js metadata to inject a canonical `` tag. No app logic changes. + +**Tech Stack:** Next.js 15 (App Router metadata API), Traefik (Docker labels), Let's Encrypt TLS. + +--- + +### Task 1: Add `.pl` domain to Traefik router + +**Files:** +- Modify: `compose.yml` + +- [ ] **Step 1: Update the Traefik router rule** + +In `compose.yml`, change the router rule label from: + +```yaml +- "traefik.http.routers.gabrielkaszewski.rule=Host(`gabrielkaszewski.dev`)" +``` + +to: + +```yaml +- "traefik.http.routers.gabrielkaszewski.rule=Host(`gabrielkaszewski.dev`) || Host(`gabrielkaszewski.pl`)" +``` + +The full `labels` block should look like: + +```yaml +labels: + - "traefik.enable=true" + - "traefik.http.routers.gabrielkaszewski.rule=Host(`gabrielkaszewski.dev`) || Host(`gabrielkaszewski.pl`)" + - "traefik.http.routers.gabrielkaszewski.entrypoints=websecure" + - "traefik.http.routers.gabrielkaszewski.tls.certresolver=letsencrypt" +``` + +Note: Traefik's Let's Encrypt cert resolver automatically provisions a cert for every hostname matched by the router rule, so no additional TLS labels are needed. + +- [ ] **Step 2: Commit** + +```bash +git add compose.yml +git commit -m "feat: add gabrielkaszewski.pl to traefik router" +``` + +--- + +### Task 2: Add canonical URL to Next.js metadata + +**Files:** +- Modify: `app/layout.tsx` + +- [ ] **Step 1: Add `alternates.canonical` to the metadata export** + +In `app/layout.tsx`, add `alternates` to the existing `metadata` object: + +```ts +export const metadata: Metadata = { + title: { + default: "Gabriel Kaszewski | Software Engineer", + template: "%s | Gabriel Kaszewski", + }, + description: + "The portfolio of Gabriel Kaszewski, a software engineer specializing in Rust, Python, and modern web technologies.", + keywords: [ + "Gabriel Kaszewski", + "Software Engineer", + "Rust Developer", + "Python Developer", + "Next.js", + "Portfolio", + ], + alternates: { + canonical: "https://gabrielkaszewski.dev", + }, + openGraph: { + // ... rest unchanged + }, + // ... rest unchanged +}; +``` + +- [ ] **Step 2: Verify the canonical tag is present in the built HTML** + +Run the dev server: + +```bash +bun run dev +``` + +Then in another terminal, check the rendered HTML for the canonical tag: + +```bash +curl -s http://localhost:3000 | grep -i canonical +``` + +Expected output: + +``` + +``` + +- [ ] **Step 3: Commit** + +```bash +git add app/layout.tsx +git commit -m "feat: add canonical URL to metadata" +```