Skip to content

fix(react): improved SSR for Next.js#683

Merged
christian-bromann merged 18 commits intomainfrom
cb/dynamic-ssr
Jul 10, 2025
Merged

fix(react): improved SSR for Next.js#683
christian-bromann merged 18 commits intomainfrom
cb/dynamic-ssr

Conversation

@christian-bromann
Copy link
Copy Markdown
Member

Pull request checklist

Please check if your PR fulfills the following requirements:

  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been reviewed and added / updated if needed (for bug fixes / features)
  • Build (npm run build) was run locally for affected output targets
  • Tests (npm test) were run locally and passed
  • Prettier (npm run prettier) was run locally and passed

Pull request type

Please check the type of change your PR introduces:

  • Bugfix
  • Feature
  • Code style update (formatting, renaming)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • Documentation content changes
  • Other (please describe):

What is the current behavior?

Currently, server-side rendered React components using Stencil only render the Declarative Shadow DOM (DSD) version on the server. There's no mechanism to dynamically load and hydrate with the actual client-side React component after initial rendering.

Issue URL: [Please provide issue URL]

What is the new behavior?

  • Added support for dynamic SSR with client-side hydration using a Next.js-like dynamic import pattern
  • Introduced new TypeScript types (DynamicImport, DynamicOptions, DynamicFunction) to support dynamic loading without requiring Next.js dependencies
  • Enhanced CreateComponentForServerSideRenderingOptions to accept dynamic function and clientModule promise
  • Modified server-side rendering to wrap components with a dynamic loader that:
    • Initially renders the Declarative Shadow DOM version (for SSR)
    • Dynamically loads and switches to the client-side component after hydration
    • Supports loading states and SSR configuration options

Does this introduce a breaking change?

  • Yes
  • No

This is an additive feature that extends the existing SSR functionality. Existing code will continue to work as before, but now developers can opt into dynamic SSR behavior by providing the new dynamic and clientModule options.

Other information

This enhancement enables a hybrid SSR approach where:

  1. The server renders Declarative Shadow DOM for initial paint and SEO
  2. The client dynamically loads the full React component for interactivity
  3. The transition is seamless with configurable loading states

This pattern is particularly useful for complex components that need both server-side rendering benefits and full client-side functionality, similar to Next.js dynamic imports but adapted for Stencil components.

@christian-bromann christian-bromann marked this pull request as ready for review July 10, 2025 16:46
@christian-bromann christian-bromann requested a review from a team as a code owner July 10, 2025 16:46
@christian-bromann christian-bromann merged commit c49a3b5 into main Jul 10, 2025
3 checks passed
@christian-bromann christian-bromann deleted the cb/dynamic-ssr branch July 10, 2025 18:47
github-actions bot pushed a commit that referenced this pull request Jan 3, 2026
## [0.11.0](https://github.com/stenciljs/output-targets/compare/@stencil/vue-output-target@0.10.8...@stencil/vue-output-target@0.11.0) (2026-01-03)

### 🚀 Enhancement

* **react:** enhance React output target with unified server/client imports and improved SSR property serialization ([132f9d9](132f9d9))
* **vue:** implement custom event property as source for v-model ([#689](#689)) ([bc385bb](bc385bb))

### 🐛 Bug Fix

* **angular:** include outputs in angular component definition ([#688](#688)) ([16f1fd1](16f1fd1)), closes [#643](#643) [#643](#643)
* **angular:** prettify code ([69e1cba](69e1cba))
* **angular:** use forwardRef in control value accessor directives. ([#697](#697)) ([dcb4bd2](dcb4bd2))
* **dependabot:** don't run updates based on projects ([3d43687](3d43687))
* **dependabot:** group updates of minor and patch versions in a single PR ([47bdb20](47bdb20))
* **dependabot:** optimize configuration ([ce29757](ce29757))
* **internal:** update changelog ([4bb6cfc](4bb6cfc))
* **react:** always use per-component CustomEvent types for event props ([#716](#716)) ([8ebba85](8ebba85)), closes [#531](#531)
* **react:** better style to css transformation ([ccc76a7](ccc76a7))
* **react:** forward ref to underlying web component ([#655](#655)) ([9f20ee0](9f20ee0))
* **react:** improved SSR for Next.js ([#683](#683)) ([c49a3b5](c49a3b5))
* **react:** properly type generated component files ([3e7cc0c](3e7cc0c))
* **vue:** remove unnecessary vue patch ([34f7ce2](34f7ce2))

### 📝 Documentation

* **internal:** link release workflow ([0e69d0e](0e69d0e))
* **internal:** update contributing guidelines ([08c96fd](08c96fd))
github-actions bot pushed a commit that referenced this pull request Jan 3, 2026
## [0.2.0](https://github.com/stenciljs/output-targets/compare/@stencil/ssr@0.1.0...@stencil/ssr@0.2.0) (2026-01-03)

### 🚀 Enhancement

* **react:** enhance React output target with unified server/client imports and improved SSR property serialization ([132f9d9](132f9d9))
* Upgraded component-library-angular to Angular 20 and added a new Angular app to example-project ([#652](#652)) ([a6fefb6](a6fefb6)), closes [#643](#643)
* **vue:** implement custom event property as source for v-model ([#689](#689)) ([bc385bb](bc385bb))

### 🐛 Bug Fix

* **#646:** react create components.ts file ([#647](#647)) ([7524cbf](7524cbf)), closes [#646](#646) [#646](#646)
* **angular:** include outputs in angular component definition ([#688](#688)) ([16f1fd1](16f1fd1)), closes [#643](#643) [#643](#643)
* **angular:** prettify code ([69e1cba](69e1cba))
* **angular:** use forwardRef in control value accessor directives. ([#697](#697)) ([dcb4bd2](dcb4bd2))
* **ci:** run in macos environment ([0631306](0631306))
* **dependabot:** don't run updates based on projects ([3d43687](3d43687))
* **dependabot:** group updates of minor and patch versions in a single PR ([47bdb20](47bdb20))
* **dependabot:** optimize configuration ([ce29757](ce29757))
* **internal:** update changelog ([4bb6cfc](4bb6cfc))
* nuxt ssr mismatch class errors ([#651](#651)) ([be797b1](be797b1))
* **react:** always use per-component CustomEvent types for event props ([#716](#716)) ([8ebba85](8ebba85)), closes [#531](#531)
* **react:** better style to css transformation ([ccc76a7](ccc76a7))
* **react:** fixed wording in component wrapper ([a83bb4b](a83bb4b))
* **react:** forward ref to underlying web component ([#655](#655)) ([9f20ee0](9f20ee0))
* **react:** improved SSR for Next.js ([#683](#683)) ([c49a3b5](c49a3b5))
* **react:** make types compatible with v18 and v19 ([f887ae7](f887ae7))
* **react:** properly type generated component files ([3e7cc0c](3e7cc0c))
* **react:** revive esModules option ([d98df24](d98df24))
* revert model update event renaming ([#649](#649)) ([5c67692](5c67692))
* **ssr:** improved SSR handling in Next.js ([#641](#641)) ([22e075f](22e075f))
* **vue:** remove unnecessary vue patch ([34f7ce2](34f7ce2))

### 📝 Documentation

* **internal:** link release workflow ([0e69d0e](0e69d0e))
* **internal:** update contributing guidelines ([08c96fd](08c96fd))
github-actions bot pushed a commit that referenced this pull request Jan 3, 2026
## [0.11.0](https://github.com/stenciljs/output-targets/compare/@stencil/vue-output-target@0.10.8...@stencil/vue-output-target@0.11.0) (2026-01-03)

### 🚀 Enhancement

* **react:** enhance React output target with unified server/client imports and improved SSR property serialization ([132f9d9](132f9d9))
* **vue:** implement custom event property as source for v-model ([#689](#689)) ([bc385bb](bc385bb))

### 🐛 Bug Fix

* **angular:** include outputs in angular component definition ([#688](#688)) ([16f1fd1](16f1fd1)), closes [#643](#643) [#643](#643)
* **angular:** prettify code ([69e1cba](69e1cba))
* **angular:** use forwardRef in control value accessor directives. ([#697](#697)) ([dcb4bd2](dcb4bd2))
* **dependabot:** don't run updates based on projects ([3d43687](3d43687))
* **dependabot:** group updates of minor and patch versions in a single PR ([47bdb20](47bdb20))
* **dependabot:** optimize configuration ([ce29757](ce29757))
* **internal:** update changelog ([4bb6cfc](4bb6cfc))
* **react:** always use per-component CustomEvent types for event props ([#716](#716)) ([8ebba85](8ebba85)), closes [#531](#531)
* **react:** better style to css transformation ([ccc76a7](ccc76a7))
* **react:** forward ref to underlying web component ([#655](#655)) ([9f20ee0](9f20ee0))
* **react:** improved SSR for Next.js ([#683](#683)) ([c49a3b5](c49a3b5))
* **react:** properly type generated component files ([3e7cc0c](3e7cc0c))
* **vue:** remove unnecessary vue patch ([34f7ce2](34f7ce2))

### 📝 Documentation

* **internal:** link release workflow ([0e69d0e](0e69d0e))
* **internal:** update contributing guidelines ([08c96fd](08c96fd))
github-actions bot pushed a commit that referenced this pull request Jan 3, 2026
## [0.2.0](https://github.com/stenciljs/output-targets/compare/@stencil/ssr@0.1.0...@stencil/ssr@0.2.0) (2026-01-03)

### 🚀 Enhancement

* **react:** enhance React output target with unified server/client imports and improved SSR property serialization ([132f9d9](132f9d9))
* Upgraded component-library-angular to Angular 20 and added a new Angular app to example-project ([#652](#652)) ([a6fefb6](a6fefb6)), closes [#643](#643)
* **vue:** implement custom event property as source for v-model ([#689](#689)) ([bc385bb](bc385bb))

### 🐛 Bug Fix

* **#646:** react create components.ts file ([#647](#647)) ([7524cbf](7524cbf)), closes [#646](#646) [#646](#646)
* **angular:** include outputs in angular component definition ([#688](#688)) ([16f1fd1](16f1fd1)), closes [#643](#643) [#643](#643)
* **angular:** prettify code ([69e1cba](69e1cba))
* **angular:** use forwardRef in control value accessor directives. ([#697](#697)) ([dcb4bd2](dcb4bd2))
* **ci:** run in macos environment ([0631306](0631306))
* **dependabot:** don't run updates based on projects ([3d43687](3d43687))
* **dependabot:** group updates of minor and patch versions in a single PR ([47bdb20](47bdb20))
* **dependabot:** optimize configuration ([ce29757](ce29757))
* **internal:** update changelog ([4bb6cfc](4bb6cfc))
* nuxt ssr mismatch class errors ([#651](#651)) ([be797b1](be797b1))
* **react:** always use per-component CustomEvent types for event props ([#716](#716)) ([8ebba85](8ebba85)), closes [#531](#531)
* **react:** better style to css transformation ([ccc76a7](ccc76a7))
* **react:** fixed wording in component wrapper ([a83bb4b](a83bb4b))
* **react:** forward ref to underlying web component ([#655](#655)) ([9f20ee0](9f20ee0))
* **react:** improved SSR for Next.js ([#683](#683)) ([c49a3b5](c49a3b5))
* **react:** make types compatible with v18 and v19 ([f887ae7](f887ae7))
* **react:** properly type generated component files ([3e7cc0c](3e7cc0c))
* **react:** revive esModules option ([d98df24](d98df24))
* revert model update event renaming ([#649](#649)) ([5c67692](5c67692))
* **ssr:** improved SSR handling in Next.js ([#641](#641)) ([22e075f](22e075f))
* **vue:** remove unnecessary vue patch ([34f7ce2](34f7ce2))

### 📝 Documentation

* **internal:** link release workflow ([0e69d0e](0e69d0e))
* **internal:** update contributing guidelines ([08c96fd](08c96fd))
johnjenkins pushed a commit that referenced this pull request Jan 3, 2026
## [0.11.0](https://github.com/stenciljs/output-targets/compare/@stencil/vue-output-target@0.10.8...@stencil/vue-output-target@0.11.0) (2026-01-03)

### 🚀 Enhancement

* **react:** enhance React output target with unified server/client imports and improved SSR property serialization ([132f9d9](132f9d9))
* **vue:** implement custom event property as source for v-model ([#689](#689)) ([bc385bb](bc385bb))

### 🐛 Bug Fix

* **angular:** include outputs in angular component definition ([#688](#688)) ([16f1fd1](16f1fd1)), closes [#643](#643) [#643](#643)
* **angular:** prettify code ([69e1cba](69e1cba))
* **angular:** use forwardRef in control value accessor directives. ([#697](#697)) ([dcb4bd2](dcb4bd2))
* **dependabot:** don't run updates based on projects ([3d43687](3d43687))
* **dependabot:** group updates of minor and patch versions in a single PR ([47bdb20](47bdb20))
* **dependabot:** optimize configuration ([ce29757](ce29757))
* **internal:** update changelog ([4bb6cfc](4bb6cfc))
* **react:** always use per-component CustomEvent types for event props ([#716](#716)) ([8ebba85](8ebba85)), closes [#531](#531)
* **react:** better style to css transformation ([ccc76a7](ccc76a7))
* **react:** forward ref to underlying web component ([#655](#655)) ([9f20ee0](9f20ee0))
* **react:** improved SSR for Next.js ([#683](#683)) ([c49a3b5](c49a3b5))
* **react:** properly type generated component files ([3e7cc0c](3e7cc0c))
* **vue:** remove unnecessary vue patch ([34f7ce2](34f7ce2))

### 📝 Documentation

* **internal:** link release workflow ([0e69d0e](0e69d0e))
* **internal:** update contributing guidelines ([08c96fd](08c96fd))
johnjenkins pushed a commit that referenced this pull request Jan 3, 2026
## [0.2.0](https://github.com/stenciljs/output-targets/compare/@stencil/ssr@0.1.0...@stencil/ssr@0.2.0) (2026-01-03)

### 🚀 Enhancement

* **react:** enhance React output target with unified server/client imports and improved SSR property serialization ([132f9d9](132f9d9))
* Upgraded component-library-angular to Angular 20 and added a new Angular app to example-project ([#652](#652)) ([a6fefb6](a6fefb6)), closes [#643](#643)
* **vue:** implement custom event property as source for v-model ([#689](#689)) ([bc385bb](bc385bb))

### 🐛 Bug Fix

* **#646:** react create components.ts file ([#647](#647)) ([7524cbf](7524cbf)), closes [#646](#646) [#646](#646)
* **angular:** include outputs in angular component definition ([#688](#688)) ([16f1fd1](16f1fd1)), closes [#643](#643) [#643](#643)
* **angular:** prettify code ([69e1cba](69e1cba))
* **angular:** use forwardRef in control value accessor directives. ([#697](#697)) ([dcb4bd2](dcb4bd2))
* **ci:** run in macos environment ([0631306](0631306))
* **dependabot:** don't run updates based on projects ([3d43687](3d43687))
* **dependabot:** group updates of minor and patch versions in a single PR ([47bdb20](47bdb20))
* **dependabot:** optimize configuration ([ce29757](ce29757))
* **internal:** update changelog ([4bb6cfc](4bb6cfc))
* nuxt ssr mismatch class errors ([#651](#651)) ([be797b1](be797b1))
* **react:** always use per-component CustomEvent types for event props ([#716](#716)) ([8ebba85](8ebba85)), closes [#531](#531)
* **react:** better style to css transformation ([ccc76a7](ccc76a7))
* **react:** fixed wording in component wrapper ([a83bb4b](a83bb4b))
* **react:** forward ref to underlying web component ([#655](#655)) ([9f20ee0](9f20ee0))
* **react:** improved SSR for Next.js ([#683](#683)) ([c49a3b5](c49a3b5))
* **react:** make types compatible with v18 and v19 ([f887ae7](f887ae7))
* **react:** properly type generated component files ([3e7cc0c](3e7cc0c))
* **react:** revive esModules option ([d98df24](d98df24))
* revert model update event renaming ([#649](#649)) ([5c67692](5c67692))
* **ssr:** improved SSR handling in Next.js ([#641](#641)) ([22e075f](22e075f))
* **vue:** remove unnecessary vue patch ([34f7ce2](34f7ce2))

### 📝 Documentation

* **internal:** link release workflow ([0e69d0e](0e69d0e))
* **internal:** update contributing guidelines ([08c96fd](08c96fd))
johnjenkins added a commit that referenced this pull request Jan 3, 2026
* chore(release): @stencil/vue-output-target@0.11.0 [skip ci]

## [0.11.0](https://github.com/stenciljs/output-targets/compare/@stencil/vue-output-target@0.10.8...@stencil/vue-output-target@0.11.0) (2026-01-03)

### 🚀 Enhancement

* **react:** enhance React output target with unified server/client imports and improved SSR property serialization ([132f9d9](132f9d9))
* **vue:** implement custom event property as source for v-model ([#689](#689)) ([bc385bb](bc385bb))

### 🐛 Bug Fix

* **angular:** include outputs in angular component definition ([#688](#688)) ([16f1fd1](16f1fd1)), closes [#643](#643) [#643](#643)
* **angular:** prettify code ([69e1cba](69e1cba))
* **angular:** use forwardRef in control value accessor directives. ([#697](#697)) ([dcb4bd2](dcb4bd2))
* **dependabot:** don't run updates based on projects ([3d43687](3d43687))
* **dependabot:** group updates of minor and patch versions in a single PR ([47bdb20](47bdb20))
* **dependabot:** optimize configuration ([ce29757](ce29757))
* **internal:** update changelog ([4bb6cfc](4bb6cfc))
* **react:** always use per-component CustomEvent types for event props ([#716](#716)) ([8ebba85](8ebba85)), closes [#531](#531)
* **react:** better style to css transformation ([ccc76a7](ccc76a7))
* **react:** forward ref to underlying web component ([#655](#655)) ([9f20ee0](9f20ee0))
* **react:** improved SSR for Next.js ([#683](#683)) ([c49a3b5](c49a3b5))
* **react:** properly type generated component files ([3e7cc0c](3e7cc0c))
* **vue:** remove unnecessary vue patch ([34f7ce2](34f7ce2))

### 📝 Documentation

* **internal:** link release workflow ([0e69d0e](0e69d0e))
* **internal:** update contributing guidelines ([08c96fd](08c96fd))

* chore(release): @stencil/react-output-target@1.2.1 [skip ci]

## [1.2.1](https://github.com/stenciljs/output-targets/compare/@stencil/react-output-target@1.2.0...@stencil/react-output-target@1.2.1) (2026-01-03)

### 🚀 Enhancement

* **vue:** implement custom event property as source for v-model ([#689](#689)) ([bc385bb](bc385bb))

### 🐛 Bug Fix

* **angular:** include outputs in angular component definition ([#688](#688)) ([16f1fd1](16f1fd1)), closes [#643](#643) [#643](#643)
* **angular:** use forwardRef in control value accessor directives. ([#697](#697)) ([dcb4bd2](dcb4bd2))
* **react:** always use per-component CustomEvent types for event props ([#716](#716)) ([8ebba85](8ebba85)), closes [#531](#531)

### 📝 Documentation

* **internal:** link release workflow ([0e69d0e](0e69d0e))
* **internal:** update contributing guidelines ([08c96fd](08c96fd))

* chore(release): @stencil/ssr@0.2.0 [skip ci]

## [0.2.0](https://github.com/stenciljs/output-targets/compare/@stencil/ssr@0.1.0...@stencil/ssr@0.2.0) (2026-01-03)

### 🚀 Enhancement

* **react:** enhance React output target with unified server/client imports and improved SSR property serialization ([132f9d9](132f9d9))
* Upgraded component-library-angular to Angular 20 and added a new Angular app to example-project ([#652](#652)) ([a6fefb6](a6fefb6)), closes [#643](#643)
* **vue:** implement custom event property as source for v-model ([#689](#689)) ([bc385bb](bc385bb))

### 🐛 Bug Fix

* **#646:** react create components.ts file ([#647](#647)) ([7524cbf](7524cbf)), closes [#646](#646) [#646](#646)
* **angular:** include outputs in angular component definition ([#688](#688)) ([16f1fd1](16f1fd1)), closes [#643](#643) [#643](#643)
* **angular:** prettify code ([69e1cba](69e1cba))
* **angular:** use forwardRef in control value accessor directives. ([#697](#697)) ([dcb4bd2](dcb4bd2))
* **ci:** run in macos environment ([0631306](0631306))
* **dependabot:** don't run updates based on projects ([3d43687](3d43687))
* **dependabot:** group updates of minor and patch versions in a single PR ([47bdb20](47bdb20))
* **dependabot:** optimize configuration ([ce29757](ce29757))
* **internal:** update changelog ([4bb6cfc](4bb6cfc))
* nuxt ssr mismatch class errors ([#651](#651)) ([be797b1](be797b1))
* **react:** always use per-component CustomEvent types for event props ([#716](#716)) ([8ebba85](8ebba85)), closes [#531](#531)
* **react:** better style to css transformation ([ccc76a7](ccc76a7))
* **react:** fixed wording in component wrapper ([a83bb4b](a83bb4b))
* **react:** forward ref to underlying web component ([#655](#655)) ([9f20ee0](9f20ee0))
* **react:** improved SSR for Next.js ([#683](#683)) ([c49a3b5](c49a3b5))
* **react:** make types compatible with v18 and v19 ([f887ae7](f887ae7))
* **react:** properly type generated component files ([3e7cc0c](3e7cc0c))
* **react:** revive esModules option ([d98df24](d98df24))
* revert model update event renaming ([#649](#649)) ([5c67692](5c67692))
* **ssr:** improved SSR handling in Next.js ([#641](#641)) ([22e075f](22e075f))
* **vue:** remove unnecessary vue patch ([34f7ce2](34f7ce2))

### 📝 Documentation

* **internal:** link release workflow ([0e69d0e](0e69d0e))
* **internal:** update contributing guidelines ([08c96fd](08c96fd))

* chore:

* Update CHANGELOG.md

---------

Co-authored-by: semantic-release-bot <semantic-release-bot@martynus.net>
Co-authored-by: John Jenkins <johnljenkins@Hotmail.com>
Co-authored-by: John Jenkins <john.jenkins@nanoporetech.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants