Using HTML slots to render platform views in the web
Summary
#
                  Flutter now renders all web platform views in a consistent location of the DOM,
                  as direct children of flt-glass-pane (regardless of the rendering backend:
                  html or canvaskit). Platform views are then "slotted"
                   into the correct
                  position of the App's DOM with standard HTML features.
                
Up until this change, Flutter web would change the styling of the rendered contents of a platform views to position/size it to the available space. This is no longer the case. Users can now decide how they want to utilize the space allocated to their platform view by the framework.
Context
#The Flutter framework frequently tweaks its render tree to optimize the paint operations that are ultimately made per frame. In the web, these render tree changes often result in DOM operations.
                  Flutter web used to render its platform views (HtmlElementView widgets)
                  directly into its corresponding position of the DOM.
                
                  Using certain DOM elements as the "target" of some DOM operations causes those
                  elements to lose their internal state. In practice, this means that iframe
                  
                  tags are going to reload, video players might restart, or an editable form
                  might lose its edits.
                
Flutter now renders platform views using slot elements inside of a single, app-wide shadow root. Slot elements can be added/removed/moved around the Shadow DOM without affecting the underlying slotted content (which is rendered in a constant location)
This change was made to:
- Stabilize the behavior of platform views in Flutter web.
 - 
                    Unify how platform views are rendered in the web for both rendering
                     backends (
htmlandcanvaskit). - 
                    Provide a predictable location in the DOM that allows developers to reliably
                     use CSS to style their platform views, and to use other standard DOM API,
                     such as 
querySelector, andgetElementById. 
Description of change
#A Flutter web app is now rendered inside a common shadow root in which slot elements represent platform views. The actual content of each platform view is rendered as a sibling of said shadow root.
Before
#...
<flt-glass-pane>
  ...
  <div id="platform-view">Contents</div> <!-- canvaskit -->
  <!-- OR -->
  <flt-platform-view>
    #shadow-root
    | <div id="platform-view">Contents</div> <!-- html -->
  </flt-platform-view>
  ...
</flt-glass-pane>
...
                    
                    
                    
                  After
#...
<flt-glass-pane>
  #shadow-root
  | ...
  | <flt-platform-view-slot>
  |   <slot name="platform-view-1" />
  | </flt-platform-view-slot>
  | ...
  <flt-platform-view slot="platform-view-1">
    <div id="platform-view">Contents</div>
  </flt-platform-view>
  ...
</flt-glass-pane>
...
                    
                    
                    
                  
                  After this change, when the framework needs to move DOM nodes around, it
                  operates over flt-platform-view-slots, which only contain a slot
                   element.
                  The slot projects the contents defined in flt-platform-view elements outside
                  the shadow root. flt-platform-view elements are never the target of DOM
                  operations from the framework, thus preventing the reload issues.
                
From an app's perspective, this change is transparent. However, this is considered a breaking change because some tests make assumptions about the internal DOM of a Flutter web app, and break.
Migration guide
#Code
#The engine may print a warning message to the console similar to:
Height of Platform View type: [$viewType] may not be set. Defaulting to `height: 100%`.
Set `style.height` to any appropriate value to stop this message.
                    
                    
                    
                  or:
Width of Platform View type: [$viewType] may not be set. Defaulting to `width: 100%`.
Set `style.width` to any appropriate value to stop this message.
                    
                    
                    
                  
                  Previously, the content returned by PlatformViewFactory functions
                   was
                  resized and positioned by the framework. Instead, Flutter now sizes and
                  positions <flt-platform-view-slot>, which is the parent of the slot where the
                  content is projected.
                
                  To stop the warning above, platform views need to set the style.width and
                  style.height of their root element to any appropriate (non-null) value.
                
                  For example, to make the root html.Element fill all the available space
                  allocated by the framework, set its style.width and style.height
                   properties
                  to '100%':
                
ui.platformViewRegistry.registerViewFactory(viewType, (int viewId) {
  final html.Element htmlElement = html.DivElement()
    // ..other props
    ..style.width = '100%'
    ..style.height = '100%';
  // ...
  return htmlElement;
});
                    
                    
                    
                  
                  If other techniques are used to lay out the platform view (like inset: 0) a
                  value of auto for width and height is enough to stop the warning.
                
                  Read more about CSS width
                   and CSS height.
                
Tests
#
                  After this change, user's test code does not need to deeply inspect the
                  contents of the shadow root of the App. All of the platform view contents will
                  be placed as direct children of flt-glass-pane, wrapped in a
                  flt-platform-view element.
                
                  Avoid looking inside the flt-glass-pane shadow root, it is considered a
                  "private implementation detail", and its markup can change at any time,
                  without notice.
                
(See Relevant PRs below for examples of the "migrations" described above).
Timeline
#
                  Landed in version: 2.3.0-16.0.pre
                  In stable release: 2.5
                
References
#Design document:
Relevant issues:
Relevant PRs:
- flutter/engine#25747: Introduces the feature.
 - 
                    flutter/flutter#82926: Tweaks 
fluttertests. - 
                    flutter/plugins#3964: Tweaks to 
pluginscode. - 
                    flutter/packages#364: Tweaks to 
packagescode. 
Unless stated otherwise, the documentation on this site reflects Flutter 3.35.5. Page last updated on 2025-10-28. View source or report an issue.