How to Share a Jupyter Notebook With Your Team (Behind Company Auth)
Convert the notebook to a single HTML file, then publish that file behind your company's login. Two commands, and the people who need to read it click a link instead of installing Jupyter.
Convert the notebook to a single HTML file, then publish that file behind your company's login. Two commands, and the people who need to read it click a link instead of installing Jupyter.
The problem with sharing a notebook
A notebook is a working file. The .ipynb is JSON: cell source, metadata, and base64-encoded outputs. Open it without Jupyter and you see the JSON, not the analysis.
So when an analyst finishes a model and a PM, a finance lead, or a VP needs to read it, the handoff breaks. The reader doesn't run Jupyter. They can't pip install anything. They want the rendered notebook (the charts, the tables, the narrative) at a URL they can open in a browser.
The common workarounds each give up something:
- Email the
.ipynb: The recipient needs Jupyter to open it. Most won't have it. - nbviewer / GitHub Gist: Renders the notebook, but the link is public. Anything with revenue numbers, customer data, or unreleased strategy can't live on a public URL.
- Google Colab: Requires every viewer to have a Google account and accept a share. Wrong for a Microsoft 365 shop, and it still exposes the editable notebook rather than a clean read-only page.
- Screenshot the charts into Slack: The interactivity dies, the tables get cropped, and there's no single source of truth.
- JupyterHub: Solves auth, but now someone runs and patches a multi-user server for what is really a read-only sharing problem.
The notebook was built in minutes. Getting one colleague to actually read it takes the rest of the afternoon.
Step 1: Export the notebook to one HTML file
nbconvert ships with Jupyter. It turns a notebook into a single self-contained HTML file with the rendered outputs embedded.
jupyter nbconvert --to html analysis.ipynbMatplotlib and Seaborn charts embed as inline images. Pandas tables render as HTML. Markdown cells become prose. The result is one file that opens in any browser with nothing else attached.
Two flags worth knowing:
jupyter nbconvert --to html --no-input analysis.ipynb
jupyter nbconvert --to html --embed-images analysis.ipynbIf you use Plotly or Bokeh and want the charts to stay interactive in the exported file, make the figures self-contained before you export. For Plotly, render with the library inlined (include_plotlyjs=True on write_html, or set the renderer so the notebook embeds the JS) so the HTML carries its own chart engine and works without a network connection.
The test for "is this one file?": move analysis.html to a different folder, open it, and confirm every chart still shows. If it does, it's ready to publish.
Step 2: Publish it behind company auth
display.dev publishes a single HTML or Markdown file to a permanent URL and puts your company's identity provider in front of it. Viewers authenticate with the Google Workspace or Microsoft 365 account they already use for email.
npm install -g @displaydev/cli
dsp login
dsp publish ./analysis.htmlPaste that URL in Slack, Notion, Jira, or the deck. Anyone with a company email clicks it, authenticates in about five seconds the first time, and reads the full rendered notebook. People outside your domain get a login wall, not the data.
This is gated publishing: one action to publish, company identity to gate, a link that works for as long as you keep it up. No per-seat charge for readers, so the eighth or eightieth person who opens the notebook costs the same as the first. That pricing matters more than it looks, because per-seat pricing actively discourages the broad internal sharing a good analysis deserves.
How the options compare
| Method | Renders for non-coders | Private to your company | Viewer needs an account | Server to maintain |
|---|---|---|---|---|
Email the .ipynb | No (needs Jupyter) | Yes | No | No |
| nbviewer / Gist | Yes | No (public) | No | No |
| Google Colab | Yes | Partly | Yes (Google) | No |
| GitHub repo render | Yes | Only on private repos | Yes (GitHub) | No |
| JupyterHub | Yes | Yes | Yes (Hub) | Yes |
| nbconvert + display.dev | Yes | Yes (SSO) | Company email only | No |
Keeping it current
When the numbers change, re-export and re-publish to the same URL so every bookmarked link updates at once:
jupyter nbconvert --to html --no-input analysis.ipynb
dsp publish ./analysis.html --id <shortId> --base-version <currentVersion>The --id targets the existing artifact and the URL stays stable. Run dsp get <shortId> to read the current version number first. Publishing without --id creates a fresh artifact at a new URL instead.
If the export is part of a scheduled job or CI run, the same command works from a pipeline. See publishing HTML from GitHub Actions for the CI recipe, including how to pass an API key instead of an interactive login.
Where this fits
Sharing a notebook is one case of a larger pattern: an analyst or an AI tool produces rich HTML, and the people who need to read it don't live in the tool that made it. The same one-command flow covers interactive data dashboards and internal docs that would otherwise get screenshotted into a thread and lost.
FAQ
Do my teammates need Python or Jupyter installed?
No. The whole point of the HTML export is that it carries its rendered outputs with it. Readers open a URL in a browser. Nothing to install, no environment to set up.
Will interactive widgets work in the exported HTML?
Static outputs (Matplotlib, Seaborn, pandas tables, Markdown) always embed. ipywidgets that depend on a live Python kernel won't, because there's no kernel behind a static file. Plotly and Bokeh stay interactive if you export the figures with their JavaScript inlined so the HTML is self-contained.
Can I hide the code and show only the results?
Yes. Add --no-input to the nbconvert command. Code cells are stripped and only the narrative, tables, and charts remain, which is usually what a non-technical stakeholder wants.
Is the published notebook actually private?
Yes. On the Pro plan, access is gated by your Google Workspace or Microsoft 365 domain. Someone without a matching company email hits a login wall and never sees the content. You can also restrict a single artifact to specific email addresses.
How is this different from nbviewer?
nbviewer renders a notebook at a public URL anyone can reach. Gated publishing renders the same notebook but limits who can open it to people who authenticate with your company identity. Same readability, opposite access model.
Free tier. No credit card. One-time password auth for viewers on free, Google + Microsoft SSO on Pro (€49/month flat).