view-html-react-js
v3.1.0
Published
Securely embed raw HTML inside a sandboxed iframe using React and TypeScript. Ideal for visualizations, maps, and WYSIWYG content.
Maintainers
Keywords
Readme
📦 view-html-react-js — Safely Render Raw HTML in React via iframe
view-html-react-jsis a lightweight React component that securely renders raw HTML content inside a sandboxed<iframe>. Ideal for embedding charts, maps, or WYSIWYG outputs, it offers security, flexibility, and full TypeScript support.
✨ Features
- 🚀 Dynamic HTML rendering using
BlobandObjectURL - 🔐 Secure sandboxing with customizable options
- 💡 Full TypeScript support with exported types
- 📐 Customizable iframe size, title, and loading behavior
- 🔗 Ref forwarding to access the underlying
<iframe>element - 🎨
className&styleprops for easy wrapper styling - 📡
onLoad&onErrorcallbacks for lifecycle events - 🌐 SSR-safe — works in Next.js (App & Pages Router)
- ⚙️ Compatible with React, Next.js, CRA, and Vite
- 🧩 Dual CJS/ESM build for maximum bundler compatibility
Use it to embed:
- Live dashboards or reports
- Visualizations from chart libraries
- HTML widgets or preview editors
- Exported WYSIWYG or CMS content
📦 Installation
npm install view-html-react-jsyarn add view-html-react-js🔧 Usage
Basic
import React from "react";
import ViewHtml from "view-html-react-js";
export default function App() {
const htmlContent = `
<!DOCTYPE html>
<html>
<head>
<style>body { margin: 0; }</style>
</head>
<body>
<h1 style="text-align:center;">Hello from Iframe</h1>
</body>
</html>
`;
return (
<ViewHtml
htmlContent={htmlContent}
options={{
iframe: {
width: "100%",
height: "80vh",
sandbox: "allow-scripts allow-same-origin",
title: "Embedded HTML View",
loading: "lazy",
},
}}
/>
);
}With className, style, and callbacks
import React from "react";
import ViewHtml from "view-html-react-js";
export default function StyledPreview() {
return (
<ViewHtml
htmlContent="<h1>Styled!</h1>"
className="preview-container"
style={{ border: "1px solid #ccc", borderRadius: 8 }}
onLoad={() => console.log("Iframe loaded!")}
onError={(e) => console.error("Iframe error:", e)}
options={{ iframe: { width: "100%", height: 400 } }}
/>
);
}With Ref Forwarding
import React, { useRef } from "react";
import ViewHtml from "view-html-react-js";
export default function WithRef() {
const iframeRef = useRef<HTMLIFrameElement>(null);
const sendMessage = () => {
iframeRef.current?.contentWindow?.postMessage("hello", "*");
};
return (
<>
<button onClick={sendMessage}>Send Message to Iframe</button>
<ViewHtml
ref={iframeRef}
htmlContent="<p>Listening for messages...</p>"
options={{ iframe: { sandbox: "allow-scripts" } }}
/>
</>
);
}Using useHtmlUrl hook
import React from "react";
import { useHtmlUrl } from "view-html-react-js";
export default function CustomIframe() {
const blobUrl = useHtmlUrl("<h1>Hello World</h1>");
if (!blobUrl) return <p>Loading...</p>;
return (
<iframe
src={blobUrl}
title="Custom"
style={{ width: "100%", height: 400 }}
/>
);
}Using useHtmlBlob hook
import React from "react";
import { useHtmlBlob } from "view-html-react-js";
export default function DownloadHtml() {
const blob = useHtmlBlob("<h1>Download Me</h1>");
const download = () => {
if (!blob) return;
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "page.html";
a.click();
URL.revokeObjectURL(url);
};
return <button onClick={download}>Download HTML</button>;
}🧩 Props
| Prop | Type | Required | Default | Description |
| ------------- | ------------------------ | -------- | ------- | -------------------------------------- |
| htmlContent | string | ✅ | – | Raw HTML string to render securely |
| className | string | ❌ | – | CSS class name for the wrapper div |
| style | React.CSSProperties | ❌ | – | Inline styles for the wrapper div |
| onLoad | () => void | ❌ | – | Called when iframe finishes loading |
| onError | (event) => void | ❌ | – | Called when iframe encounters an error |
| ref | Ref<HTMLIFrameElement> | ❌ | – | Ref forwarded to the iframe element |
| options | object | ❌ | {} | Iframe configuration (see below) |
options.iframe
| Prop | Type | Default | Description |
| --------- | ------------------- | ----------- | ----------------------------- |
| width | string \| number | "100%" | Width of the iframe |
| height | string \| number | "100%" | Height of the iframe |
| title | string | "Preview" | Accessible title attribute |
| sandbox | string | "" | Sandbox policy for the iframe |
| loading | "eager" \| "lazy" | "lazy" | Loading behavior |
🪝 Hooks
useHtmlUrl(htmlContent: string): string | null
Creates a temporary Blob URL from HTML content. Automatically cleans up old URLs when content changes to prevent memory leaks. SSR-safe.
useHtmlBlob(htmlContent: string): Blob | null
Creates a Blob from HTML content. Useful for downloading or custom processing. SSR-safe.
🔒 Security Note
The default sandbox setting does not allow any scripts. Add allow-scripts if needed.
⚠️ Warning: Always sanitize user-generated HTML before rendering it with view-html-react-js. Avoid injecting untrusted content directly.
🌐 SSR Compatibility
This package is SSR-safe out of the box. The hooks detect server-side environments and return null until the component is mounted on the client.
🧠 Use Cases
- Embedding data visualizations (Chart.js, D3, Plotly)
- Integrating third-party maps (e.g., Leaflet, Mapbox)
- Previewing CMS/WYSIWYG HTML output
- Rendering HTML reports or templates
- Communicating with iframe content via
postMessage(using ref forwarding)
🧪 Compatibility
- ✅ React 17+
- ✅ TypeScript & JavaScript
- ✅ Next.js (App/Pages Router, SSR-safe)
- ✅ Vite / CRA / Webpack / Rollup
📄 License
MIT License
