Skip to content

fix(docs): move the guide's scripts out of the page to satisfy the CSP - #12

Merged
paulosfjunior merged 1 commit into
mainfrom
fix/docs-csp
Sep 23, 2026
Merged

paulosfjunior merged 1 commit into
mainfrom
fix/docs-csp

Conversation

@paulosfjunior

Copy link
Copy Markdown
Contributor

The published guide had every one of its scripts blocked. The theme toggle, the language toggle and the nav highlight worked locally and did nothing at all on tooark.com.

The policy

Content-Security-Policy:
  default-src 'self';
  script-src  'self' https://static.cloudflareinsights.com;
  style-src   'self' 'unsafe-inline' https://fonts.googleapis.com;
  font-src    https://fonts.gstatic.com;
  img-src     'self' data: ...

script-src has no 'unsafe-inline', so an inline <script> is refused. The console showed one violation per block:

Executing inline script violates the following Content Security Policy directive
'script-src 'self' https://static.cloudflareinsights.com'. The action has been blocked.

Note what the same policy does allow, because it shaped the fix: style-src keeps 'unsafe-inline', so the page's inline <style> is fine, and Google Fonts are explicitly allowed for both the stylesheet and the font files. Only scripts had to move.

The fix

All three blocks are now docs/guide.js, same origin, which 'self' permits.

  • Loaded from <head> without defer, on purpose: theme and language still have to be stamped on <html> before the first paint or the page flashes the wrong one.
  • Everything that touches the DOM waits for DOMContentLoaded.
  • node --check docs/guide.js passes.

The button labels moved into data- attributes on the buttons. So guide.js now contains no human-readable string at all — a wording change is a change to the HTML, next to the rest of the translations, and there is no second place for a translation to hide. It also sidesteps any question about the charset a .js file is served with.

Not fixed, because it is not ours

The fourth violation in the console (:2511) is an inline script Cloudflare injects into the response for its bot-detection platform. The same policy blocks it. Nothing in this repository produces or can suppress it — it would need a change on the Cloudflare side.

Affected area(s)

  • docs/ — onboarding guide

Consumer impact

  • No consumer-visible change

Checklist

  • node --check docs/guide.js passes
  • HTML still balanced — 0 unclosed tags
  • Zero inline <script> left in the page
  • ./scripts/check-sync.sh passes
  • CHANGELOG.md updated under [Unreleased]

🤖 Generated with Claude Code

The site is served behind

  script-src 'self' https://static.cloudflareinsights.com

with no 'unsafe-inline', so every inline <script> on the page was blocked. The
theme toggle, the language toggle and the nav highlight all worked locally and
did nothing at all on the published page — the console showed one CSP violation
per script block.

They now live in docs/guide.js, same origin, which 'self' allows. It is loaded
from <head> without defer because the theme and language still have to be
stamped on <html> before the first paint; everything that touches the DOM waits
for DOMContentLoaded.

The button labels moved into data- attributes on the buttons themselves. That
keeps every piece of translated text in the HTML beside the rest of the
translations, and it means the script file has no string that a change of
wording would have to reach.

Not fixed here, because it is not ours: Cloudflare injects its own inline
script into the response, and the same policy blocks that too.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@paulosfjunior
paulosfjunior merged commit d39412f into main Sep 23, 2026
5 checks passed
@paulosfjunior
paulosfjunior deleted the fix/docs-csp branch September 23, 2026 00:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant