# 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" ```