You’ve run into a very real ATS (Applicant Tracking System) problem, and you’re right about the core issue:
window.print() itself is not the enemy — how the page is rendered is.
The good news: you can keep your Astro + JS/TS CMS workflow and still generate an ATS-parsable CV, without falling back to Word or LaTeX.
Below is a practical, production-grade breakdown, ordered from most important to nice-to-have.
- Understand what ATS scanners actually need
Most ATS systems don’t do OCR unless they have to. They expect:
✅ Real text, not images
✅ Logical reading order
✅ Simple layout (single column preferred)
✅ Standard fonts
✅ Semantic structure
When scanners fail with print() PDFs, it’s usually because:
Text is rendered as SVG / Canvas / background images
CSS positioning breaks reading order
Fonts are embedded in a way that flattens glyphs
The PDF lacks tags
- Audit why your current PDF becomes images
Common culprits in modern web CVs:
❌ CSS that causes rasterization
Avoid:
transform: scale(); filter: blur(); backdrop-filter; mix-blend-mode;
Browsers will flatten the entire page into images if these appear in the print context.
❌ Icon fonts & SVG-only text
Font Awesome icons
SVG-based headings
Inline elements
ATS often ignores or misreads these.
- Create a print-specific ATS-safe layout (critical)
In Astro, add a dedicated print stylesheet:
@media print { * { transform: none !important; filter: none !important; box-shadow: none !important; } body { font-family: "Times New Roman", Arial, sans-serif; font-size: 11pt; line-height: 1.4; } a::after { content: " (" attr(href) ")"; font-size: 9pt; } }
Key principles:
One column
No grids or absolute positioning
No icons
No decorative separators
- Use semantic HTML (this helps ATS a lot)
This is where your CMS really shines.
✅ Do this
Firstname Lastname
Senior Frontend Engineer
Experience
Company – Role
2021–2024
❌ Avoid
Experience
...
ATS systems do parse headings, lists, and articles.
- Fonts: boring is good
Use:
Times New Roman
Arial
Helvetica
Georgia
Avoid:
Variable fonts
Custom web fonts in print
Icon fonts
In print CSS:
@media print { body { font-family: Arial, sans-serif; } }
- Stop using browser print → use a PDF renderer instead (important)
Browsers are inconsistent. Instead, generate PDFs using a headless renderer that preserves text.
Best options
✅ Puppeteer (recommended for JS/TS stacks)
await page.pdf({ format: "A4", printBackground: false, preferCSSPageSize: true, tagged: true });
Why this works:
Preserves text layers
Generates selectable text
Can produce tagged PDFs
✅ Playwright (similar benefits)
❌ Avoid
html2canvas
jspdf with canvas
Screenshot-based exporters
- Create a dedicated /cv-print route
This is a pro move.
Example:
/cv → styled portfolio version /cv-print → ATS-safe version
In Astro:
--- const isPrint = Astro.url.pathname.includes("cv-print"); ---
Then conditionally:
Disable icons
Switch layout
Simplify styles
- Tagged PDFs (optional but excellent)
Some ATS systems read PDF tags (structure tree).
If you use:
Puppeteer
PrinceXML (paid)
WeasyPrint (via CI)
You can generate fully tagged PDFs, similar to LaTeX output.
This is why Overleaf works so well.
- Test your output like an ATS
Before sending:
Open PDF
Try:
Select text
Copy → paste into plain text editor
Upload to:
Indeed resume parser
LinkedIn resume upload
Jobscan.co
If it pastes cleanly → you’re good.
- Reality check (important)
ATS-friendly ≠ visually impressive
That’s why even FAANG candidates often submit:
One boring PDF
One beautiful portfolio
Your CMS approach is actually better than Word/LaTeX — you just need two outputs.
TL;DR (what to do next)
Keep your stack. Change the export.
✅ Semantic HTML
✅ Print-only ATS stylesheet
✅ No transforms, SVG text, or icons
✅ Generate PDF with Puppeteer/Playwright
✅ Separate /cv-print route
If you want, I can:
Review your existing CV markup and point out ATS-breaking parts
Give you a Puppeteer PDF export script tailored to Astro
Help design a clean ATS-only layout that auto-syncs with your CMS
Just tell me which you want.
You’ve run into a very real ATS (Applicant Tracking System) problem, and you’re right about the core issue:
window.print() itself is not the enemy — how the page is rendered is.
The good news: you can keep your Astro + JS/TS CMS workflow and still generate an ATS-parsable CV, without falling back to Word or LaTeX.
Below is a practical, production-grade breakdown, ordered from most important to nice-to-have.
Most ATS systems don’t do OCR unless they have to. They expect:
✅ Real text, not images
✅ Logical reading order
✅ Simple layout (single column preferred)
✅ Standard fonts
✅ Semantic structure
When scanners fail with print() PDFs, it’s usually because:
Text is rendered as SVG / Canvas / background images
CSS positioning breaks reading order
Fonts are embedded in a way that flattens glyphs
The PDF lacks tags
Common culprits in modern web CVs:
❌ CSS that causes rasterization
Avoid:
transform: scale(); filter: blur(); backdrop-filter; mix-blend-mode;
Browsers will flatten the entire page into images if these appear in the print context.
❌ Icon fonts & SVG-only text
Font Awesome icons
SVG-based headings
Inline elements
ATS often ignores or misreads these.
In Astro, add a dedicated print stylesheet:
@media print { * { transform: none !important; filter: none !important; box-shadow: none !important; } body { font-family: "Times New Roman", Arial, sans-serif; font-size: 11pt; line-height: 1.4; } a::after { content: " (" attr(href) ")"; font-size: 9pt; } }
Key principles:
One column
No grids or absolute positioning
No icons
No decorative separators
This is where your CMS really shines.
✅ Do this
Firstname Lastname
Senior Frontend Engineer
Experience
Company – Role
2021–2024❌ Avoid
ATS systems do parse headings, lists, and articles.
Use:
Times New Roman
Arial
Helvetica
Georgia
Avoid:
Variable fonts
Custom web fonts in print
Icon fonts
In print CSS:
@media print { body { font-family: Arial, sans-serif; } }
Browsers are inconsistent. Instead, generate PDFs using a headless renderer that preserves text.
Best options
✅ Puppeteer (recommended for JS/TS stacks)
await page.pdf({ format: "A4", printBackground: false, preferCSSPageSize: true, tagged: true });
Why this works:
Preserves text layers
Generates selectable text
Can produce tagged PDFs
✅ Playwright (similar benefits)
❌ Avoid
html2canvas
jspdf with canvas
Screenshot-based exporters
This is a pro move.
Example:
/cv → styled portfolio version /cv-print → ATS-safe version
In Astro:
--- const isPrint = Astro.url.pathname.includes("cv-print"); ---
Then conditionally:
Disable icons
Switch layout
Simplify styles
Some ATS systems read PDF tags (structure tree).
If you use:
Puppeteer
PrinceXML (paid)
WeasyPrint (via CI)
You can generate fully tagged PDFs, similar to LaTeX output.
This is why Overleaf works so well.
Before sending:
Open PDF
Try:
Select text
Copy → paste into plain text editor
Upload to:
Indeed resume parser
LinkedIn resume upload
Jobscan.co
If it pastes cleanly → you’re good.
ATS-friendly ≠ visually impressive
That’s why even FAANG candidates often submit:
One boring PDF
One beautiful portfolio
Your CMS approach is actually better than Word/LaTeX — you just need two outputs.
TL;DR (what to do next)
Keep your stack. Change the export.
✅ Semantic HTML
✅ Print-only ATS stylesheet
✅ No transforms, SVG text, or icons
✅ Generate PDF with Puppeteer/Playwright
✅ Separate /cv-print route
If you want, I can:
Review your existing CV markup and point out ATS-breaking parts
Give you a Puppeteer PDF export script tailored to Astro
Help design a clean ATS-only layout that auto-syncs with your CMS
Just tell me which you want.