To place content from an HTML-generated PDF on top of pages in an existing PDF, first render the HTML to its own PDF, then use a PDF library to draw each source page onto the corresponding destination page. With PyMuPDF, that operation is Page.show_pdf_page(). It overlays page content; it does not append pages, and it does not copy the source page’s links, annotations, or form widgets.
Overlaying pages is different from merging or appending
An overlay combines content on the same page: the existing PDF remains the destination, and content from the HTML-generated PDF is placed over or behind its pages. Appending or merging instead inserts pages into the document’s page sequence. Those operations solve different problems.
- Use an overlay when, for example, generated text, a label, or a watermark must appear on an existing page.
- Use page insertion or merging when the generated PDF should become additional pages in the document.
PyMuPDF’s FAQ describes the distinction directly: insert_pdf() adds pages, while show_pdf_page() overlays content on an existing page. The examples below use the latter.
Prepare the HTML-generated PDF
Overlaying requires a PDF source document; it does not place raw HTML onto a PDF page. Render the HTML first, then open the resulting PDF alongside the existing PDF. PyMuPDF documents HTML-to-PDF generation using its Story and DocumentWriter classes: a story is laid out within a page rectangle and written into a PDF document.
#1 Best Overall
The HTML renderer determines the source PDF’s page size and layout. Before overlaying, decide whether its pages are intended to cover the whole destination page or a smaller area. If the source and destination page dimensions or proportions differ, a full-page placement may scale or position content differently than intended.
Overlay with PyMuPDF
Install PyMuPDF in your Python environment, make sure both input PDFs exist, and run this example. It overlays each source page onto the destination page with the same index, placing the source content in the foreground and saving to a new file.
import pymupdf
source = pymupdf.open("html-generated.pdf")
destination = pymupdf.open("existing.pdf")
for index, page in enumerate(destination):
if index < source.page_count:
page.show_pdf_page(page.rect, source, index, overlay=True)
destination.save("overlaid.pdf")
source.close()
destination.close()
This example assumes that page 0 in the generated PDF belongs on page 0 in the existing PDF, page 1 belongs on page 1, and so on. It overlays only as many pages as the source contains. Destination pages without a corresponding source page remain unchanged.
Overlay selected pages
If only some destination pages should receive the generated content, filter the destination loop. For example, to overlay source page 0 on destination page 2, use the destination page’s zero-based index:
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →import pymupdf
source = pymupdf.open("html-generated.pdf")
destination = pymupdf.open("existing.pdf")
destination[2].show_pdf_page(
destination[2].rect,
source,
0,
overlay=True,
)
destination.save("overlaid.pdf")
source.close()
destination.close()
PDF page indices are zero-based in this example: index 0 is the first page. Check that the selected source index exists before calling the method. For a large set of page mappings, represent the intended destination-to-source pairs explicitly rather than relying on accidental index alignment.
Place content in a smaller area
The first argument to show_pdf_page() is the destination rectangle. Passing page.rect targets the full destination page. To position content within a smaller region, provide a rectangle with the desired coordinates in the destination page’s coordinate system. Consider the rectangle, aspect ratio, clipping, and any requested rotation together; changing one can affect how the source content fits.
PyMuPDF also supports preserving proportions and clipping. Consult the installed version’s API reference for the precise method signature and parameters before using those controls. The full-page example deliberately leaves the default placement behavior in place rather than guessing at custom geometry.
Rank #2
- Keep track of everything from attendance to test scores
- Spiral bound
- Measures 8-1/2" x 11"
Choose foreground or background placement
With overlay=True, the source content is placed in the foreground. Set overlay=False to place it behind the existing page content. The order matters: foreground content can obscure underlying text or graphics, while background content can be hidden by opaque material already on the page.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minuteCheck alignment, appearance, and interactivity
Save to a separate output file so the original remains available for comparison and recovery. Open representative pages in a PDF viewer and check that the generated content lands where intended, is not clipped, and appears in the correct foreground or background order. Include pages with different layouts or page sizes in that review.
- Geometry: Check page dimensions and proportions. A full-page rectangle is suitable only when the intended mapping is full-page; otherwise, specify a deliberate target rectangle.
- Clipping: Confirm that text and graphics near the source page edges remain visible after placement.
- Visibility: Confirm that foreground content does not hide important destination material and that background content is not covered unexpectedly.
- Interactive content:
show_pdf_page()does not copy annotations, widgets, or links from the source page. A clickable link or form element in the HTML-generated PDF should not be assumed to remain interactive in the result. Use a workflow that preserves or recreates those elements if they are required.
Other library paths and when they fit
| Option | Good fit | Important distinction |
|---|---|---|
| Python with PyMuPDF | One Python-based path for documented HTML-to-PDF generation and page-content overlay. | show_pdf_page() places source-page content on a destination page; source annotations, widgets, and links are not copied. |
| JavaScript with pdf-lib | Projects using JavaScript in a browser or Node that need to modify PDFs, draw text or images, or embed pages from another PDF. | Use the API documentation for the installed version to determine exact page-placement code and behavior. |
| Python with pypdf | Appending or merging page sequences. | The cited merging guidance establishes page-sequence operations, not an HTML-rendering workflow or a preferred same-page overlay method. |
There is no universal winner established for every project. Choose based on your runtime, the precision of placement you need, whether interactive elements must survive, and the constraints of your deployment environment.
Troubleshooting common overlay problems
The generated pages appear after the existing document
This usually means the operation added pages instead of drawing source-page content on destination pages. Use an overlay operation such as show_pdf_page() when the content must share an existing page; page insertion or merging changes the document’s sequence.
Nothing appears on a page
Check the source page index, confirm that it contains visible content, and verify that the loop is reaching the intended destination page. If the page mapping is not one-to-one, an index-based loop may be targeting the wrong page; specify the intended source and destination indices explicitly.
Content is too large, small, or misplaced
Compare the source and destination page geometry and confirm that the destination rectangle is the intended one. If the dimensions or proportions differ, set placement and clipping deliberately instead of assuming that page.rect will produce the desired visual alignment.
Existing content disappears behind the overlay
Check the foreground/background setting. Use overlay=False when the source content should be placed behind the existing page content, and review the result because existing opaque graphics may then cover it.
Rank #3
Links or form controls no longer work
This is a limitation of the overlay method: it places page content but does not copy source annotations, widgets, or links. If those elements matter, choose a process that handles them separately or recreate them in the destination PDF, then verify their behavior in a viewer.
The output is missing or cannot be reopened
Check that the input paths are correct, the process can read both PDFs, and the output path is writable. Save under a new filename rather than overwriting the original input; then open the output in a PDF viewer to verify that it was written successfully.
Recommended Free Tools
Or skip the browser setup
ScreenshotNeo is a website screenshot API, not a PDF-page overlay library. It can capture a URL as an image or PDF, but it does not replace the PyMuPDF operation above when you already have two PDFs and need to compose their pages. If the material you need is still available as a webpage, a single request can capture it without configuring a browser yourself. See the ScreenshotNeo documentation for request options.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
- Cookie and consent banners are accepted and removed before capture, along with known newsletter popups and chat widgets; each cleanup step can be turned off.
- Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed. Responses identify page verdict and billing status in headers.
- An MCP server provides
take_screenshot,get_page_info, andcapture_pdftools for AI agents and other MCP clients. - The free plan includes 1,000 screenshots per month with no card required; paid plans start at $5 for 3,000 shots.
Sign up for ScreenshotNeo: get 1,000 free screenshots a month with no card.
Frequently asked questions
Can I overlay a PDF produced from HTML without converting it first?
No. The overlay method places a PDF page onto another PDF page. Render the HTML as a PDF first, then use that PDF as the source.
Can the source PDF have more pages than the existing PDF?
Yes, but the example only overlays source pages that have matching destination indices. To place additional source pages, define a mapping to existing destination pages; to add them as new pages instead, use a page insertion or merge workflow.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




