Conversation
Patch real <title>, <meta name="description">, OG tags, Twitter Card tags, and a canonical link into the outer shell of docs/index.html and docs/site/user-guide.html — the bytes a crawler sees before any JS runs. The bundler leaves that shell with an empty <title>Bundled Page</title> and no description, so search results and link previews had nothing to show. tools/build-user-guide/inject-seo-metadata.py sources every value from the page's own real content (title/h1/paragraphs), never fabricated copy, and is idempotent via a marker comment so re-running it replaces rather than duplicates. It also replaces the old generic "This page requires JavaScript to display" <noscript> fallback with the real h1 and intro paragraphs. It never touches the inner __bundler/template span, so the page itself is unchanged — verified byte-identical to the inner content on main. build-user-guide.sh now runs the injector after check-bundle-js.py in the default build path, and again before the manifest is pinned in --record mode, so both bundles always carry the metadata and .user-guide.manifest's hash reflects it. Add docs/robots.txt and docs/sitemap.xml, an allow-all robots file pointing at a sitemap listing the two actually-crawlable published URLs (the root page and the user guide) — not the internal hash-fragment routes, which aren't separately crawlable.
simonkrol
marked this pull request as ready for review
October 2, 2026 18:32
simonkrol
requested review from
georgebearden,
ihmaws,
knihit and
shsenior
as code owners
October 2, 2026 18:32
This branch has not been deployed
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.
SEO / discoverability:
tools/build-user-guide/inject-seo-metadata.py— patches the outer bundler-shell<head>ofdocs/index.htmlanddocs/site/user-guide.html(the bytes a crawler sees before any JS runs) with a real<title>,<meta name="description">, Open Graph tags, a Twitter Card type, and a canonical link, all sourced from the page's own real content. Replaces the generic "This page requires JavaScript to display"<noscript>fallback with the real<h1>and intro paragraphs. Idempotent (marker-based) and never touches the inner__bundler/templateJSON span.tools/build-user-guide/build-user-guide.sh: wires the injector into the build pipeline (default build mode, aftercheck-bundle-js.pypasses; and--recordmode, before the manifest is pinned), so both published bundles always carry the injected metadata and the manifest hash reflects it.docs/index.html,docs/site/user-guide.html: regenerated through the pipeline (not hand-edited). Only the outer shell changed — the inner page content is byte-identical tomain(verified via SHA-256 of the extracted__bundler/templatespan).docs/site/.user-guide.manifest: re-pinned to the new output hash sobuild-user-guide.sh --check/make guide-checksee no drift from this change.docs/social-preview.png(1200×1200) — a static PNG render of the logo mark already used on the bundler's own loading screen (#__bundler_thumbnail's inline SVG, identical in both bundles). Used asog:image, so link unfurls (Slack, LinkedIn, Facebook, and Twitter/X via its OG fallback) show a real image instead of none.docs/robots.txt— standard allow-all robots file pointing at the sitemap.docs/sitemap.xml— lists the two genuinely distinct published URLs (https://aws-solutions.github.io/konductor/andhttps://aws-solutions.github.io/konductor/site/user-guide.html). Deliberately excludes internal hash-fragment routes (e.g.#/tasks), which aren't separately crawlable.Social card tags, specifically:
twitter:cardis set tosummary_large_image(the layout only — it carries no image of its own). Notwitter:title,twitter:description, ortwitter:imageare set; Twitter/X falls back toog:title/og:description/og:imagewhen those are absent, so duplicating the same values under both prefixes would have been redundant.Known, deliberate deviation from "single bundled page, no network calls": that requirement (in
tools/build-user-guide/BUILD_USER_GUIDE_PROMPT.md) is about the guide opening viafile://with no build step and no network fetch (besides the already-accepted Google Fonts link).og:imageis a web convention that only works by pointing at a separately-fetchable HTTP(S) URL — it cannot be satisfied by an embedded data URI in practice (most unfurlers, including Twitter's, expect a real URL, not adata:URI).docs/social-preview.pngis therefore a second static file living alongside the bundle, not embedded in it. This does not affect the file://-offline use case — nothing in the rendered page loads this image; it's metadata read only by external link-unfurling crawlers after the page is shared, never fetched by a browser opening the HTML file itself. It does mean the guide is no longer strictly a single file. Flagging this explicitly as an intentional, scoped exception rather than an oversight.Deliberately excluded from this PR:
README.md— doc: README updates to include links to Workshop and User Guide #32 is already open adding the GitHub Pages link there; touching it here would conflict.Fixes # (no linked issue)
Type of Change
Build tooling (
tools/build-user-guide/) and generated GitHub Pages output (docs/).Testing
make guide-checkbefore and after this change. One failure persists in both cases — check [10],`config` is listed as withdrawn from the guide, but cli/README.md no longer declares it— confirmed viagit stashto be identical on cleanmain, i.e. pre-existing and unrelated to this change. No new failures introduced.__bundler/templatespan of both regenerated bundles is byte-identical (SHA-256) to the same span onmain— only the outer shell changed.docs/social-preview.pngis a valid PNG (1200×1200, RGBA) and is staged/committed, not left untracked, so the referenced URL will resolve once published.inject-seo-metadata.pya second time against already-patched files produces byte-identical output.Not applicable here:
npm test(no JS/TS source changed),cd cli && make test(nocli/Rust/Python source changed — this touchestools/build-user-guide/, a separate script, not thecli/crate), agent/skill benchmark harness (no agent or skill behavior changed).Checklist
Notes for Reviewers
make guide-checkcheck [10] fails onmainas well as on this branch (confirmed viagit stash):`config` is listed as withdrawn from the guide, but cli/README.md no longer declares it — drop it from WITHDRAWN_COMMANDS. Out of scope here; flagging so it isn't mistaken for a regression from this change.<h1>and paragraph text — nothing is invented.social-preview.pngis likewise a faithful render of an asset already present in the bundle (the loading-screen SVG), not a new design.og:imageand the single-file-bundle requirement — happy to discuss if a different tradeoff is preferred (e.g. dropping the image tags entirely to stay strictly single-file).docs/index.htmlanddocs/site/user-guide.htmlare generated artifacts; please don't review them line-by-line — reviewinject-seo-metadata.pyand thebuild-user-guide.shwiring, and treat the two HTML diffs as their output.Example Linkedin Post:

Tested Pages build: https://simonkrol.github.io/konductor/