SEO, structured data, accessibility and custom domain - #11
Merged
Conversation
Search:
- title and description now carry the words people actually search
('automatic keyboard layout switching for macOS'); the page previously
never said 'automatically' or 'external' about itself
- canonical link, robots directives, sitemap.xml, .nojekyll
- JSON-LD: SoftwareApplication, SoftwareSourceCode, Person, WebSite and
FAQPage. No aggregateRating - there are no reviews yet and inventing them
is a manual-action risk. The 7 schema FAQ entries match the 7 visible on
the page verbatim, which Google requires
- two new FAQ answers targeting the queries a landing page cannot otherwise
reach: the German-keyboard-on-a-US-MacBook case, and how this differs from
autokbisw and Input Source Pro
Accessibility (real defects, not nits):
- both ASCII boards had aria-label on a bare <pre>. ARIA prohibits labelling
a roleless element, so the label was dropped and screen readers read ~2600
punctuation characters aloud instead. Adding role='img' makes the label
authoritative and replaces the subtree
- decorative CSS content ('# ', '[+]', '>') was being announced; now paired
with empty alt text
- the h1 rendered as 'keyboard.Not the app' with no space in its text content
- header and main landmarks
Housekeeping: the art generators were being served as web content from
docs/; moved to Scripts/ alongside release.sh.
Custom domain inputpilot.lucagerlich.dev: CNAME file plus all 14 absolute
URLs rewritten across index.html, sitemap.xml and robots.txt.
There was a problem hiding this comment.
Pull request overview
This PR updates the GitHub Pages landing site for InputPilot to improve technical SEO and accessibility, and switches the Pages deployment to a custom domain (inputpilot.lucagerlich.dev).
Changes:
- Adds SEO essentials (canonical URL, robots directives, sitemap.xml) and JSON-LD structured data to
docs/index.html. - Fixes accessibility issues around the keyboard ASCII art labeling and decorative generated content.
- Moves GitHub Pages to a custom domain via
docs/CNAME(and adds.nojekyll).
Reviewed changes
Copilot reviewed 10 out of 20 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| Scripts/generate-keyboard-html.py | Generates HTML-wrapped keyboard ASCII art segments and emits JSON for the site. |
| Scripts/generate-keyboard-art.py | Renders ANSI/ISO keyboard art into a sampled ASCII grid and ownership map. |
| docs/sitemap.xml | Adds a sitemap pointing to the new canonical domain. |
| docs/robots.txt | Adds a robots file referencing the sitemap on the new domain. |
| docs/index.html | Updates SEO meta, adds JSON-LD, and adjusts accessibility + page copy/structure. |
| docs/CNAME | Configures GitHub Pages to serve from inputpilot.lucagerlich.dev. |
| docs/.nojekyll | Disables Jekyll processing on GitHub Pages. |
| .playwright-mcp/page-2026-08-18T20-59-20-768Z.yml | Playwright artifact (appears unrelated to InputPilot) committed into the repo. |
| .playwright-mcp/page-2026-08-18T20-58-00-900Z.yml | Playwright artifact (appears unrelated to InputPilot) committed into the repo. |
| .playwright-mcp/page-2026-08-18T20-57-37-579Z.yml | Playwright artifact (appears unrelated to InputPilot) committed into the repo. |
| .playwright-mcp/page-2026-08-18T20-57-26-140Z.yml | Playwright artifact (appears unrelated to InputPilot) committed into the repo. |
| .playwright-mcp/page-2026-08-18T20-57-10-025Z.yml | Playwright artifact (appears unrelated to InputPilot) committed into the repo. |
| .playwright-mcp/page-2026-08-18T20-57-00-353Z.yml | Playwright artifact (appears unrelated to InputPilot) committed into the repo. |
| .playwright-mcp/console-2026-08-18T20-58-35-992Z.log | Playwright artifact (appears unrelated to InputPilot) committed into the repo. |
| .playwright-mcp/console-2026-08-18T20-57-58-830Z.log | Playwright artifact (appears unrelated to InputPilot) committed into the repo. |
| .playwright-mcp/console-2026-08-18T20-57-36-725Z.log | Playwright artifact (appears unrelated to InputPilot) committed into the repo. |
| .playwright-mcp/console-2026-08-18T20-57-25-970Z.log | Playwright artifact (appears unrelated to InputPilot) committed into the repo. |
| .playwright-mcp/console-2026-08-18T20-57-04-795Z.log | Playwright artifact (appears unrelated to InputPilot) committed into the repo. |
| .playwright-mcp/console-2026-08-18T20-57-00-122Z.log | Playwright artifact (appears unrelated to InputPilot) committed into the repo. |
Suppressed comments (2)
docs/index.html:154
- Same issue here:
content:"›" / ""can be parsed as invalid on browsers without support for the alt-text form, which would drop the visible›marker. Add a plaincontent:fallback first.
ul.checks li::before { content:"›" / ""; position:absolute; left:.3rem; color:var(--green); }
docs/index.html:161
content:"[+]" / ""andcontent:"[-]" / ""have the same compatibility risk as other generated-content markers: if the alt-text syntax isn’t supported, the whole declaration can be ignored and the disclosure affordance disappears. Add a plaincontent:fallback before the alt-text form.
summary::after { content:"[+]" / ""; color:var(--faint); }
details[open] summary::after { content:"[-]" / ""; }
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| section { padding:3.5rem 0; border-top:1px solid var(--line); } | ||
| h2 { font-size:1.15rem; margin:0 0 .4rem; letter-spacing:-0.01em; } | ||
| h2::before { content:"# "; color:var(--faint); } | ||
| h2::before { content:"# " / ""; color:var(--faint); } |
Comment on lines
+1
to
+5
| - generic [active] [ref=f15e1]: | ||
| - banner [ref=f15e3]: | ||
| - link "jump to content" [ref=f15e4] [cursor=pointer]: | ||
| - /url: "#content" | ||
| - generic [ref=f15e6]: |
Comment on lines
+1
to
+5
| [ 34616ms] [ERROR] Client Error: "TypeError: Cannot read properties of null (reading 'match')" thrown at L14:31141 in https://web.archive.org/web/20260618201204js_/https://www.redditstatic.com/reddit-init.en.BddHLmUiRRw.js Message: "Uncaught TypeError: Cannot read properties of null (reading 'match')" {tag: unknown} @ https://web-static.archive.org/_static/js/wombat.js?v=o9P2E1FK:20 | ||
| [ 34623ms] TypeError: Cannot read properties of null (reading 'match') | ||
| at Object.parseTrackingCookie (https://web.archive.org/web/20260618201204js_/https://www.redditstatic.com/reddit-init.en.BddHLmUiRRw.js:14:31141) | ||
| at Object.getLoIdData (https://web.archive.org/web/20260618201204js_/https://www.redditstatic.com/reddit-init.en.BddHLmUiRRw.js:14:30919) | ||
| at Object.getTrackingData (https://web.archive.org/web/20260618201204js_/https://www.redditstatic.com/reddit-init.en.BddHLmUiRRw.js:14:30772) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Applies the technical SEO audit, fixes two real accessibility defects, and moves the site to inputpilot.lucagerlich.dev.
This PR contains
docs/CNAME. GitHub Pages switches to the custom domain the moment it deploys, and redirects the oldgithub.ioURL there. Add the DNS record before merging, or the site is unreachable in the gap:inputpilotlucagerlich.github.io.There is a wildcard
*.lucagerlich.dev→ 46.62.169.116 (Hetzner) today, so the subdomain currently resolves to your server; an explicit CNAME takes precedence over the wildcard.Search
Title and description now contain the terms people search — the page never previously said "automatically" or "external" about itself. Adds canonical, robots directives, sitemap.xml, .nojekyll, and JSON-LD (SoftwareApplication, SoftwareSourceCode, Person, WebSite, FAQPage). No
aggregateRating: there are no reviews, and fabricating them risks a manual action. The 7 FAQ entries in schema match the 7 visible on the page verbatim, as Google requires.Two new FAQ answers target queries a landing page cannot otherwise reach: the German-keyboard-on-a-US-MacBook case, and how this differs from autokbisw and Input Source Pro — comparison searches convert far better than generic ones.
Accessibility — two genuine defects
aria-labelon a bare<pre>. ARIA prohibits labelling a roleless element, so the label was silently dropped and screen readers read ~2,600 punctuation characters aloud.role="img"makes the label authoritative and replaces the subtree.#,[+],›) was being announced as "number sign", "left bracket plus". Now paired with empty alt text.keyboard.Not the appwith no space.Verified
JSON-LD parses and validates; schema FAQ count matches visible count; no stale
github.ioURLs remain.One audit finding I rejected
The audit reported that
appcast.xmlstill advertises 1.0.0, which would mean 1.0.0 users never get updates. I checked the live feed and the local file: both correctly say 1.0.1, build 2. The agent read a stale copy — no change made.