S-switch / s-checkbox checked state flicker

Hey Shopify nerds :nerd_face:

I’m building an app and use the Polaris s-switch / s-checkbox components to show checked/unchecked states (obviously).
The one thing that I do not understand is that the initial state of checked is true, but I do not know why or how to prevent this.

Every time I load the page, the switch flickers from true to false, even when I hardcode it to false. Does anyone know why or know how to fix that?

ezgif-2cc89e55479815e6

What kind of context are you using this in? e.g React? Can you create a sharable example? For example, I don’t get that behavior when I use it like this: https://codepen.io/afrehner/pen/jErqdKB

Are you using SSR in React? It could be the difference between pre- and post-hydration, too.

This is what happens in SSR, for checkboxes + switches (and maybe others?), it defaults to ‘on/checked’:

CleanShot 2026-01-07 at 17.24.19

I believe this may be due to how React handles SSR-ing web components; I believe it sends the raw HTML, which has

<s-switch checked="false">

or something like that. When our component sees the attribute checked, it sets the defaultChecked property. In this case, setting it to true, because it’s a boolean attribute.

But then React client-side hydration comes, and when it the attribute checked, it sets the checked property, and correctly parses the false to set the property.

So you would need to have some logic in your SSR code to prevent that flickering.

1 Like

Right - can confirm this is the issue. For anyone else - setting the value to true | undefined, rather than true | false, seems to work well for ‘disabled’, ‘checked’ etc.

Hey @bkspace and @Anthony_Frehner thank you so much for replying!
Im actually not the best when it comes to React, therefore I need to educate myself about terms like SSR and Hydration :smiley: But still makes sense what you are writing.

For the Codepen example: It actually does not work again when you write out the attributechecked=”false”on the element itself.
The Context in which I’m using it is the normal App default template, when you create a React Router app, no fancy additions :slight_smile:
It also doesn’t work when I set defaultChecked to false.

Its not a big deal, but could be irritating for users. On the other hand I think that lot’s of apps should show this behaviour then, which makes it fine.

Take a look at my link above about “boolean attributes”. :+1:

Yes, makes absolute sense! Thank you, and will work with that information :slight_smile: