A screenshot, an HTML attachment, Datawrapper, Flourish, Tableau Public, a public site, a drive, or a private link: what each one is built for, who ends up able to see the chart, and why the same Plotly chart can be 4.8 MB or 12 KB.
You built the chart in a notebook: a Plotly figure with hover values, a legend you can click, a zoom that finds the odd week in the data. The person who needs to see it runs no Python and never will. Paste a screenshot into the email and all of that is gone. The first question they ask ("what's that spike in March?") is the one the screenshot can't answer.
There are plenty of ways to put a chart on a link. They differ most in one thing: who ends up able to see it.
This matters more than it looks.
If you're still picking, a hosted charting tool is a real option. You upload the data, build the chart in their editor, and publish it from there. Datawrapper and Flourish are very good at that.
If you already have the chart, say a Plotly, Bokeh or Altair figure you've spent an afternoon on, those same tools mean building it again from the data in someone else's editor. What you have is code that can write a self-contained HTML file. The question is where that file should go.
The rest of this page compares both kinds of route, because people search for both, but it's written for the person holding the file.
| Way | What the reader gets | What it's built for | Where it gets awkward |
|---|---|---|---|
| A screenshot or PNG | A picture of the chart | A slide, a quick answer in chat | Nothing hovers, zooms or toggles, so follow-up questions come back to you |
| An HTML attachment | A file in their downloads folder | Handing over the file itself | Some mail systems strip or block scripts in HTML attachments, so the chart can arrive dead |
| Datawrapper or Flourish | A published, embeddable chart | Charts for articles and public reports | You rebuild the chart in their editor, and publishing on the free plans makes it public |
| Tableau Public | A published visualisation | Public BI dashboards and data portfolios | Public is the design: what you save there can be seen by anyone |
| GitHub Pages or Netlify | A page on a public website | Public sites that live with their code | The page is on the open web, and setup is heavier than one chart needs |
| Google Drive or Dropbox | A file in a drive viewer | Files a team keeps working on | A drive shows or downloads the HTML file rather than running the chart |
| A private-link host (miinideck) | The live chart in their browser, from an unguessable address kept out of search | A finished chart going to specific people | It hosts the file you made; it doesn't build charts or connect to live data |
Whether a published chart is public is the detail that decides most of this. It's set by each service's plans, and plans change, so it comes from their own pages and it's dated.
| Who can see what you publish | A private or password option | |
|---|---|---|
| Datawrapper | Anyone: once you publish, the chart is public | Not for published charts, on any plan |
| Flourish | Anyone, on the free plan | Password-protected publishing on the Publisher and Enterprise plans |
| Tableau Public | Anyone; it's a public platform | Not on Tableau Public; Tableau points private data to its other products |
| GitHub Pages | Anyone on the internet | Not on the free plan |
| miinideck | Only people who have the link; kept out of search | A password, free on any account |
Checked against each service's own pricing and help pages on 1 October 2026. Every service sets its own plans and changes them without telling us, so check their site for what's current. Our own row comes from our plan limits.
An interactive chart is two things: your data, and the JavaScript library that draws it. The library can live inside the HTML file, or the file can fetch it from a CDN (a public server that hosts the library) when someone opens it. We exported the same Plotly figure both ways on 30 September 2026.
Packed in (the default for fig.write_html()): the file came out at 4.8 MB. It works with no internet connection, from a downloads folder, anywhere. The cost is the size.
From the CDN (fig.write_html("chart.html", include_plotlyjs="cdn")): the file came out at 12 KB. The catch is that the reader's browser has to reach Plotly's CDN when they open it. On a locked-down corporate network, or offline on a train, the chart doesn't appear.
How to choose:
Bokeh and Altair make the same choice with different switches: Bokeh between inline and CDN resources, Altair with an option to inline its libraries when saving. We only measured Plotly. The trade-off is the same.
A chart library that fails to load is the most common way a chart file breaks on delivery. If an AI wrote the chart for you, prompt patterns for a self-contained chart or dashboard covers the prompts that stop that from happening.
The data travels with the chart. To show a hover value, the browser has to have that value, so an interactive chart carries its data inside the file. Anyone who opens it can read the data with the browser's developer tools, whatever host you use. If the figure plots row-level customer data and the reader only needs monthly totals, aggregate before you export.
A file doesn't update itself. An exported chart is a snapshot of the data at export time. If the reader needs numbers that stay current without you re-exporting, that's a dashboard with a live connection, and it needs a server behind it. How to share a dashboard without giving a login covers when that's worth it.
Anything on a screen can be captured. A private link controls who can open the chart, not what they do once they're looking at it.
That's the job miinideck is built around: a finished chart, going to specific people, still interactive when it arrives.
You upload the HTML file your code wrote. The reader opens the link in any browser and gets the real chart: hover values, legend toggles, box zoom, double-click to reset. There's no Python, no account and nothing to install on their side.
The link ends in 32 random characters, so nobody can guess it, and the page tells search engines not to index it. That keeps unreleased numbers out of search. Anyone you send the link to can open it, and so can anyone they forward it to. When the figure carries revenue or headcount, put a password on it. It's free on any account.
After you send it, the link is still yours:
Here are the size limits. A No-account upload takes files up to 3 MB, runs for 7 days, and can't be replaced. The packed-in Plotly export from our test was over that line, and the CDN version was well under it. The Free tier takes 10 MB per file. Solo ($4.99/mo) takes 25 MB and Studio ($14.99/mo) takes 50 MB.
For how this fits alongside every other kind of file you might need to hand over, see where to put a file online.
If your chart is a Plotly figure, share a Plotly chart walks through the export and the upload step by step.
A test send, your ESP's preview, a rendering-test service, a screenshot, the .html as an attachment, or a hosted page link: what each one shows the client, what a browser preview can and can't prove about an email, and the combination that gets sign-off without surprises.
Postman's published docs, SwaggerHub, a hosted docs portal, GitHub Pages, the raw OpenAPI file, or one rendered HTML page behind a private link: what each is built for, how to turn a spec into a single page with one command, and what to strip out before anyone outside sees it.
Quarto Pub, RPubs, Posit Connect Cloud, GitHub Pages or Netlify, an HTML attachment, or a private link: what each one is built for, why a rendered report loses its styling when you send the HTML on its own, and which route fits a report meant for a client or an advisor.
miinideck turns a single HTML file into an unguessable link with optional password and expiry. Default-private, never indexed.