Skip to content

feat: support documentTitle for PDF printing via document.title guard#724

Open
danielrose7 wants to merge 2 commits into
crabbly:masterfrom
danielrose7:feat/document-title-pdf
Open

feat: support documentTitle for PDF printing via document.title guard#724
danielrose7 wants to merge 2 commits into
crabbly:masterfrom
danielrose7:feat/document-title-pdf

Conversation

@danielrose7
Copy link
Copy Markdown

@danielrose7 danielrose7 commented Apr 23, 2026

Summary

  • For PDF iframes, Chrome uses document.title (not the iframe's <title>) for "Save as PDF" filenames. Since print() is deferred via setTimeout, there's a window between setting the title and Chrome actually reading it — during which a framework (React <Head>, Vue router, etc.) can reset it.
  • Adds a MutationObserver-based guard that holds document.title to the desired value across that window, catching and reverting any mutations. Falls back gracefully when MutationObserver is unavailable.
  • Adds documentTitleHoldMs param (default 3000ms) to let users tune the hold duration.

Closes #487
Closes #66

Reference

Standalone helper with writeup: https://gist.github.com/danielrose7/adb604b9334118d98de6e856efd043df

Test plan

Manual test cases are included in test/manual/index.html — run npm start (or serve the project root) and click:

  • "Print PDF with documentTitle" — Chrome's save dialog should show "My Custom Report" as the filename
  • "Print PDF with documentTitle (simulated framework reset)" — aggressively resets document.title every 50ms to prove the MutationObserver guard holds

Additional checks:

  • Verify non-PDF types (html, image, json) still work as before (no title guard, immediate cleanup)
  • Verify that the original document.title is restored after the hold period
  • Test with documentTitleHoldMs: 500 to verify custom hold durations work

🤖 Generated with Claude Code

For PDF iframes, Chrome uses document.title (not the iframe's <title>)
for "Save as PDF" filenames. Since print() on a PDF iframe is
non-blocking, Chrome reads document.title asynchronously after return.

This adds a MutationObserver-based guard that temporarily holds
document.title to the desired value, preventing framework re-renders
(React <Head>, Vue router, etc.) from resetting it during that window.

Adds documentTitleHoldMs param (default 3000ms) to let users tune the
hold duration.

Closes crabbly#487
Closes crabbly#66

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Two buttons added:
- "Print PDF with documentTitle" — basic test, verify Chrome's print
  dialog shows "My Custom Report" as the filename
- "Print PDF with documentTitle (simulated framework reset)" — uses a
  setInterval to aggressively reset document.title, proving the
  MutationObserver guard holds the title stable

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

Add option to control PDF filenames when users download print results through browser preview Unable to set a file name

1 participant