Skip to main content
iVentureTeam

iframe_wrapper

For HTML that is a whole document rather than a fragment: styles, head metadata, the lot. It writes the value straight into an iframe, and the source explains at length why.

Siddharth JambukiyaSiddharth JambukiyaOdoo Techno-Functional Consultant
August 27, 2026Updated August 27, 20265 min read
Technical nameiframe_wrapper
Field typestext, html
Viewsform
Moduleweb, present in every Odoo database
Used in coreUsed for previewing complete server-generated documents
VersionsOdoo 20.0, Odoo 19.0, Odoo 18.0, Odoo 17.0, Odoo 16.0
No-code setupNo. It needs a field holding a full HTML document
Alternativeshtml, pdf_viewer, text, google_slide_viewer

What the iframe wrapper field does

Odoo's rich text field is for fragments: a paragraph, a list, some formatting inside a page that already has its own styles. It is the wrong tool for a value that is a complete HTML document, because the document's own styles would leak into the interface around it and its head metadata would be discarded.

This widget solves that by putting the document in an iframe. Inside that frame the document has its own root, its own head and its own styles, and none of it reaches the Odoo page. What renders is what a browser would render if you opened the value as a file.

It is purely a viewer. There is no editing, no toolbar and no way to change the value from the widget; whatever produced the document is responsible for its content.

What this means for your team

The use case is previewing something generated elsewhere: a rendered report, a templated email, a supplier's document. Showing it as a fragment inside the form either breaks the layout or misrepresents the output, and both are worse than not showing it.

The constraint worth planning for is sanitization. On an HTML field, Odoo strips markup it considers unsafe, and a complete document is mostly markup of exactly that kind: head tags, style blocks, meta elements. The widget's own source flags this, and the practical consequence is that a preview like this usually needs the field configured to keep its content intact, which is a decision to make deliberately rather than discover.

Working examples

On a text field

<field name="rendered_document"
       widget="iframe_wrapper"/>

A text field is the simplest carrier, because nothing sanitizes its content.

On an HTML field

# on the model, so the document survives
body = fields.Html(sanitize=False)

Without relaxing sanitization the head and styles are removed before rendering, which is what the source comment warns about.

What it is not

<field name="body" widget="html"/>

The rich text editor, for fragments users edit. This widget is a viewer for whole documents.

Why it writes rather than builds

The implementation is one effect. When the field's value changes, the widget opens the iframe's document, writes the value into it and closes it. That is the entire rendering path.

Using document.write is unusual enough that the source carries a paragraph justifying it. The argument is that the alternative, building the document through DOM methods, forces the frame to be created with its own html, head and body already in place, so the value would have to be split into pieces and appended individually, which makes attributes on the outermost nodes and complex parsing awkward. Writing the string wholesale sidesteps all of it.

Because the write is inside an effect keyed on the value, a recomputed document does refresh in place, unlike several other viewer widgets in Odoo that read their value once at startup.

Two limits follow from the approach. The frame has no source attribute, so the document runs in the page's own origin rather than sandboxed, and nothing in the widget restricts what the document may contain. That is fine for server-generated content and worth thinking about for anything else.

Version compatibility

VersionStatusNotes
Odoo 20.0In developmentNot released. Behavior unchanged on the development branch.
Odoo 19.0VerifiedVerified against the shipped source. Identical to Odoo 18.
Odoo 18.0VerifiedIdentical behavior.
Odoo 17.0VerifiedSame approach with older component conventions.
Odoo 16.0VerifiedSame approach with older component conventions.

Upgrade note. The widget has been present with this approach since Odoo 16, and the Odoo 18 and Odoo 19 files are identical. There is nothing to migrate in views; what matters on any upgrade is that the field's sanitize configuration still lets the document through.

What is changing in Odoo 20

Odoo 20 is expected at Odoo Experience in Brussels, 24 to 26 September 2026. The development branch is unstable and this may still change; we re-verify this page after the release.

Behavior is unchanged. The write into the frame, the effect keyed on the value and the supported types are all identical. The differences are internal, following the wider component migration.

Common problems and fixes

SymptomCause and fix
Styles and head content are missingThe field sanitizes its HTML, stripping the metadata before the widget renders it. Relax the field's sanitize configuration, which the source comment warns about, or store the document in a text field.
The frame is emptyThe field holds nothing, or the value is not a document. Check what the server writes into the field.
The document does not refreshIt should; the write is keyed on the value. Confirm the field actually changed rather than a related one.
The document's styles affect the pageThey should not, since the document is inside a frame. Check that the widget is really in use rather than a plain HTML field.
It cannot be editedIntended. The widget is a viewer with no editing path. Use the rich text widget where editing is needed.
Options are ignoredThe widget declares none and has no extractor. Nothing to configure here.

Iframe wrapper field vs the alternatives

WidgetBest forKey difference
iframe_wrapperPreviewing a complete HTML document without its styles leakingWrites the value into an iframe, refreshing whenever the value changes
htmlFragments users editAn editor, and its content shares the page's styles
pdf_viewerDocuments that are PDFsRenders a PDF rather than HTML
textShowing the markup itselfPrints the source rather than rendering it
google_slide_viewerEmbedding a hosted presentationFrames an external URL rather than stored markup

Use the rich text widget for fragments users edit, and the PDF viewer where the document is a PDF rather than HTML. Where the content is untrusted, neither this widget nor a plain HTML field is the right answer; a sandboxed preview or a server-side conversion is.

Frequently asked questions

Why does it use document.write?+
A comment in the source explains it: building the document through DOM methods would force the frame to be created with its own html, head and body, so the value would have to be split up and appended piece by piece. Writing the string wholesale avoids that.
Why is my styling missing?+
Almost always sanitization. On an HTML field Odoo strips head tags and style blocks, and the widget's own source warns to adjust the sanitize settings. A text field avoids the problem entirely.
Can users edit the document?+
No. The widget only renders; there is no editing path at all.
Does it refresh when the value changes?+
Yes. The write is inside an effect keyed on the field's value, unlike several viewer widgets that read once at startup.
Is the content sandboxed?+
No. The frame has no source attribute and runs in the page's origin, so this is intended for server-generated content rather than untrusted input.

Previews that show what the customer will actually get

Rendered documents, templated emails and printed layouts diverge from the preview in ways nobody notices until a customer does. We build and verify Odoo document generation on versions 16 through 19.

Book a free consultation

How this page was produced

The single effect, the write into the frame, the justifying comment and the sanitize warning were read from iframe_wrapper_field.js on the Odoo 19.0 branch. Version coverage comes from comparing the file across the 16.0, 17.0 and 18.0 branches and against the public development branch. Spotted an error? Tell us and we will correct the page.