Add website screenshots and PDFs to a Bubble app
Written by the SnapRender team. SnapRender is the screenshot service behind the plugin used in this guide; its free plan covers 200 captures a month. A lot of Bubble apps end up needing a picture of a web page. A direct
Written by the SnapRender team. SnapRender is the screenshot service behind the plugin used in this guide; its free plan covers 200 captures a month.
A lot of Bubble apps end up needing a picture of a web page. A directory wants a thumbnail for every listed site. A client portal wants a record of what a landing page looked like on launch day. An internal tool wants to read a competitor's pricing page and summarize it. Bubble has no built-in way to capture a page, and the usual workaround (an API Connector call you set up and debug yourself) takes longer than it should.
This guide uses the free SnapRender Screenshot API plugin from the Bubble marketplace. It adds four calls to your app:
| Call | Where it shows in Bubble | What it gives you |
|---|---|---|
| Take Screenshot | Workflow action | A PNG, JPEG, WebP or PDF file stored in your app |
| Create Signed Screenshot URL | Data source | A link that renders a fresh screenshot when opened |
| Extract Content | Workflow action | The page as Markdown, text, HTML, the main article, links or metadata |
| Get Usage | Data source | Your plan and captures used this month |
We will set it up, then build four small features with it.
Step 1: get an API key
Sign up at app.snap-render.com with Google, GitHub or email. The key is on your dashboard right away and starts with sk_live_. The free plan has 200 captures a month and does not ask for a card.
Step 2: install the plugin
- Open your app in the Bubble editor and go to the Plugins tab.
- Select Add plugins, search SnapRender, and install SnapRender Screenshot API. It is free.
- Back in the Plugins tab, select the plugin and paste your key into the X-API-Key field.
That is the whole setup. The marketplace page is here: SnapRender Screenshot API on Bubble.
Recipe 1: save a screenshot of a URL a user submits
Say your app has a Site data type and users add sites through a form. You want a screenshot saved on each record.
First, add a field to the data type: screenshot, of type image.
Then build the workflow:
- Event: When Button Save is clicked.
-
SnapRender: Take Screenshot. Set url to Input URL's value and format to
png. Leave width and height at their defaults (1280 x 800) for a normal desktop view. - Data: Make changes to a thing. Pick the Site the user just created and set screenshot to Result of step 1.
Take Screenshot returns a file that Bubble stores in your app, so step 3 saves a real file, not a link that might stop working. To show it, add an Image element and set its source to the Site's screenshot field.
A few fields worth knowing on Take Screenshot:
- full_page captures the whole scrollable page instead of the first screen.
- dark_mode asks the page for its dark theme, where it has one.
- block_ads and block_cookie_banners are on by default, so the screenshot shows the page and not a consent popup.
- delay (0 to 10,000 ms) waits before the capture, for pages that fill in after they load.
Phone-sized screenshots. Version 1.0.0 of the plugin has no device presets. For a typical phone view, set width to 390 and height to 844. Turn on full_page if you want the whole page at that width.
Recipe 2: live preview thumbnails in a repeating group
Storing a file is right when you want a fixed record. For a list that should always look current, a signed link is simpler: nothing is stored, and the image is rendered when someone opens the page.
- Add a Repeating group with type of content Site and data source Do a search for Sites.
- Put an Image element in the first cell.
- Set the image's dynamic source to Get data from an external API, pick SnapRender: Create Signed Screenshot URL, set url to Current cell's Site's url, and take its signed_url.
The signed link carries a signature, not your API key, so it is safe to show to visitors. expires_in sets how long it works, from 60 seconds up to 30 days (2,592,000 seconds); the default is one day.
One thing to plan for: creating the link is free, but every time an image loads, the link is opened and that uses one capture. A repeating group of 50 rows that 100 people view is 5,000 captures. Keep the group paged to a handful of rows, or use Recipe 1 for lists that many people browse.
Recipe 3: turn a page into Markdown for an AI step
Language models read Markdown far better than raw HTML. Extract Content gives you that in one step.
- Event: When Button Analyze is clicked.
-
SnapRender: Extract Content. Set url to Input URL's value and type to
markdown. - API Connector: your OpenAI or Claude call, with Result of step 1's content inside the prompt.
- Data: Make changes to a thing to save the answer, or show it in a Text element.
Set up the AI call in Bubble's API Connector as you normally would: your provider key in a private header, and a body parameter for the page text. Two tips:
-
type
articlekeeps only the main text of the page and drops menus and footers, which makes for a shorter, cheaper prompt. - The result also has wordCount. Check it before sending a very long page to a model with a small context window.
Other types are useful too: links returns every link on the page, metadata returns the title, description and social preview tags.
Recipe 4: a PDF of a page on a button click
- Event: When Button Download PDF is clicked.
-
SnapRender: Take Screenshot. Set url to the page, format to
pdfand full_page to yes. - Navigation: Open an external website, with the destination set to Result of step 1. The PDF opens in a new tab where the user can save it.
Because the PDF is a file in your app, you can also keep it with a Make changes to a thing step, for example on an Order or a Report record. If the PDF must match exactly what a visitor saw, including the cookie banner, turn block_cookie_banners and block_ads off.
Keeping an eye on usage
Get Usage is a data source with your plan, the current period's start and end, and screenshots_used, screenshots_limit and screenshots_remaining. Put it in a Text element on an admin page and you will see your month at a glance. It uses no captures.
Cost
The plugin is free. Captures come from your SnapRender plan: the free plan has 200 a month, and paid plans start at $9 for 2,000. Each screenshot, extraction or opened signed link uses one capture. Creating a signed link, checking usage and failed captures use none.
On the Bubble side, each call counts toward your app's workload units, billed by Bubble.
Troubleshooting
-
The page could not be reached: check that the URL opens in a private browser window. SnapRender captures public pages only, so pages behind a login or on
localhostwill not work. - A security check instead of the page ("Just a moment..."): the site's firewall does not recognize SnapRender. If it is your own site, one rule lets it through: allow SnapRender on your site.
- A blank or half-loaded screenshot: add a delay of 1,000 to 3,000 ms so the page has time to finish.
The setup page, with every call and field listed, is here: SnapRender for Bubble.
Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.