Skip to content

feat(web-components): add SSR support via Declarative Shadow DOM modules#36247

Open
radium-v wants to merge 50 commits into
microsoft:masterfrom
radium-v:users/radium-v/wc-add-ssr-support
Open

feat(web-components): add SSR support via Declarative Shadow DOM modules#36247
radium-v wants to merge 50 commits into
microsoft:masterfrom
radium-v:users/radium-v/wc-add-ssr-support

Conversation

@radium-v
Copy link
Copy Markdown
Contributor

Previous Behavior

@fluentui/web-components had no server-side rendering path. Components were defined and rendered only on the client, so SSR frameworks could not pre-render Fluent web components into HTML and hydrate them on load.

The e2e tests ran against a custom harness that only covered client-side rendering.

New Behavior

@fluentui/web-components now supports SSR via Declarative Shadow DOM, built on @microsoft/fast-element and @microsoft/fast-html. Every component in the package ships a paired define-async.ts / *.definition-async.ts module so its template can render on the server and hydrate on the client.

The build also emits two new asset types alongside the JS modules, one pair per component (42 of each), exposed through new package subpath exports:

  • @fluentui/web-components/<component>/template.html: declarative HTML template wrapped in <f-template>, consumed by @microsoft/fast-html to render Declarative Shadow DOM on the server.
  • @fluentui/web-components/<component>/styles.css: plain CSS extracted from the component's styles, importable as a raw stylesheet without pulling in the component's JS.

Currently, the SSR templates and styles are generated at build time and placed in the dist output, but we may want to provide them as src assets in the future for easier consumption and customization.

New test harness modules (test/src/entry-client.ts, test/src/entry-server.ts) and a test/ssr.html entry point template exercise the DSD output end-to-end. The e2e pipeline runs SSR tests after CSR tests.

Several components needed template or base adjustments to render correctly under SSR: tooltip (anchor positioning polyfill handling), text-input, textarea, tree, and tree-item. The theme/set-theme tests are skipped under SSR.

Next Steps

This PR lays the groundwork for SSR support in @fluentui/web-components, but there are still some follow-up tasks to complete:

  • Update to the latest @microsoft/fast-element and remove the @microsoft/fast-html dependency, as DSD rendering will be directly supported in FAST in the next major release.
  • Provide more detailed documentation and examples for using the SSR templates and styles.
  • Add more comprehensive SSR tests covering edge cases and hydration scenarios.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 26, 2026

📊 Bundle size report

✅ No changes found

@github-actions
Copy link
Copy Markdown

Pull request demo site: URL

Comment thread packages/web-components/src/accordion/accordion.definition-async.ts
Comment thread packages/web-components/src/accordion-item/define-async.ts Outdated
Comment thread packages/web-components/src/dropdown/dropdown.base.ts Outdated
Comment thread packages/web-components/src/menu/define-async.ts Outdated
Comment thread packages/web-components/src/textarea/textarea.spec.ts Outdated
Comment thread packages/web-components/src/tooltip/tooltip.ts
Comment thread packages/web-components/src/tree-item/tree-item.base.ts Outdated
@radium-v radium-v force-pushed the users/radium-v/wc-add-ssr-support branch from b80881f to 3ebabb7 Compare May 26, 2026 15:41
@@ -0,0 +1,7 @@
{
Copy link
Copy Markdown

@github-actions github-actions Bot May 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🕵🏾‍♀️ visual changes to review in the Visual Change Report

vr-tests-react-components/Menu Converged - submenuIndicator slotted content 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/Menu Converged - submenuIndicator slotted content.default - RTL.submenus open.chromium.png 404 Changed
vr-tests-react-components/Positioning 2 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/Positioning.Positioning end.chromium.png 34 Changed
vr-tests-react-components/Positioning.Positioning end.updated 2 times.chromium.png 762 Changed
vr-tests-react-components/ProgressBar converged 3 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/ProgressBar converged.Indeterminate + thickness - High Contrast.default.chromium.png 175 Changed
vr-tests-react-components/ProgressBar converged.Indeterminate + thickness.default.chromium.png 117 Changed
vr-tests-react-components/ProgressBar converged.Indeterminate + thickness - Dark Mode.default.chromium.png 61 Changed
vr-tests-react-components/TagPicker 2 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/TagPicker.disabled - Dark Mode.disabled input hover.chromium.png 658 Changed
vr-tests-react-components/TagPicker.disabled.disabled input hover.chromium.png 677 Changed
vr-tests-web-components/Avatar 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-web-components/Avatar. - Dark Mode.normal.chromium.png 10380 Changed
vr-tests-web-components/MenuList 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-web-components/MenuList. - Dark Mode.normal.chromium.png 498 Changed
vr-tests/Callout 6 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests/Callout.Top center.default.chromium.png 2127 Changed
vr-tests/Callout.Left top edge.default.chromium.png 2183 Changed
vr-tests/Callout.Root.default.chromium.png 2195 Changed
vr-tests/Callout.No callout width specified.default.chromium.png 2143 Changed
vr-tests/Callout.Right top edge.default.chromium.png 1126 Changed
vr-tests/Callout.Top left edge.default.chromium.png 2212 Changed
vr-tests/Coachmark 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests/Coachmark.Collapsed.default.chromium.png 159 Changed
vr-tests/react-charting-LineChart 2 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests/react-charting-LineChart.Multiple - RTL.default.chromium.png 200 Changed
vr-tests/react-charting-LineChart.Multiple - Dark Mode.default.chromium.png 181 Changed
vr-tests/react-charting-VerticalBarChart 2 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests/react-charting-VerticalBarChart.Grouped - Wrap Labels.default.chromium.png 3105 Changed
vr-tests/react-charting-VerticalBarChart.Basic - Secondary Y Axis.default.chromium.png 3 Changed

There were 4 duplicate changes discarded. Check the build logs for more information.

@radium-v radium-v force-pushed the users/radium-v/wc-add-ssr-support branch from ac9d18f to 7531a73 Compare May 26, 2026 19:45
@github-actions github-actions Bot added the CI label May 26, 2026
@radium-v radium-v force-pushed the users/radium-v/wc-add-ssr-support branch from 7531a73 to 4601fe9 Compare May 26, 2026 20:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants