ionic-team / stencil-ds-output-targets

These are output targets that can be added to Stencil for React and Angular.

Home Page:https://stenciljs.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

bug: ClassName not transformed and appplied when using Serverside Rendering

mayerraphael opened this issue · comments

Prerequisites

Stencil Version

2.23

Stencil Framework Output Target

React

Stencil Framework Output Target Version

0.5.3

Current Behavior

When using className property on a Stencil component wrapper, the className is only applied on hydration. The className property is not applied when using NextJS serverside rendering.

The problems seems to be that className is only transformed on componentDidMount, which does not trigger using serverside rendering (the Stencil hydrate package).

See:

const { children, forwardedRef, style, className, ref, ...cProps } = this.props;

You deconstruct props and assign className to a variable, but it is never used.

This bug can cause layout shifts because classNames are only applied once the component is hydrated.

Expected Behavior

ClassNames should be transformed to a class attribute on first run, not after componentDidMount.

Steps to Reproduce

<my-component className="123" />

Code Reproduction URL

donothave.com

Additional Information

No response

Thanks for the issue! This issue has been labeled as needs reproduction. This label is added to issues that need a code reproduction.

Please reproduce this issue in a Stencil project and provide a way for us to access it (GitHub repo, etc). Without a reliable code reproduction, it is unlikely we will be able to resolve the issue, leading to it being closed.

If you have already provided a code snippet and are seeing this message, it is likely that the code snippet was not enough for our team to reproduce the issue.

@rwaskiewicz Is there really a example necessary?

There className is declared, but never used in the code.
image

Also the reason why it works on the client is becaus of:

componentDidMount() {
    this.componentDidUpdate(this.props);
  }

  componentDidUpdate(prevProps: StencilReactInternalProps<ElementType>) {
    attachProps(this.componentEl, this.props, prevProps);
  }

Here all the props, including className, are attached. But this does not happen using React/SSR.

I guess what is needed is that className is transformed to class before the first render, not only with componentDidUpdate, which causes the initial render to be invalid in the sense that css classes are missing on the element (be it on the server or on the client).

@mayerraphael a simple reproduction of a Next.js app with this problem would help us with verifying the issue against a proposed fix.

I'm not entirely sure why className is not passed into the newProps when constructing the element wrapper, but that would be where I would likely start to see if assigning it directly on the element resolves the issue in your environment.

Is this an issue you would be open to contributing towards?

Thanks for the issue! This issue is being closed due to the lack of a code reproduction. If this is still an issue with the latest version of the output targets, please create a new issue and ensure the template is fully filled out.