Material UI server side rendering

Hi there!

I’m looking to use JSONForms. Given my first experiment with it, I’m finding it really easy to use a well done.

In you project we are trying to server side render every things, but the Material UI renderer render nothing on server side by default. By lookink in the forum and the issue I found this old thread: Server side rendering

Given the answer I tried to force the MUI render on server side but with no luck:

export const theme = createTheme({
  components: {
    MuiUseMediaQuery: {
      defaultProps: {
        ssrMatchMedia: () => {
          return { matches: true };
        },
      },
    },
  },

  // ...
});

Is there a way to server side render the form?

Thanks for your help!

Hi @armandabric,

We’re still using the Hidden component which does not render by default on the server. You could try setting the implementation='css' prop via the default props mechanism of Material UI.

Thank you for responding so quickly. I understand now why there is not SSR.

After looking at your suggested fix, I could not find any way to set the implementation="css" globally to be able to force the JSONForms Hidden component to use it.

As the Hidden component is deprecated did you want me to try a PR to modernize this and use the media queries?

After looking at your suggested fix, I could not find any way to set the implementation="css" globally to be able to force the JSONForms Hidden component to use it

You’re right, I can’t find MuiHidden within the createTheme/components, maybe because it’s deprecated.

As the Hidden component is deprecated did you want me to try a PR to modernize this and use the media queries?

That would be amazing!

After a quick search in the codebase, I see two usages of the Hidden component:

  • The main one: to only render on client side
    <Hidden xsUp={!visible}>
      <TextField
        required={showAsRequired(required,
          appliedUiSchemaOptions.hideRequiredAsterisk)}
        id={id + '-input'}
        label={label}
        type={fieldType}
        error={!isValid}
        disabled={!enabled}
        fullWidth={!appliedUiSchemaOptions.trim}
        onFocus={onFocus}
        onBlur={onBlur}
        helperText={!isValid ? errors : showDescription ? description : null}
        InputLabelProps={{ shrink: true }}
        value={inputValue}
        onChange={onChange}
      />
    </Hidden>
  • Another one: to hidde the fieldset FormControl on big screen
    <Hidden xlUp={!visible}>
      <FormControl component='fieldset'>
        <FormGroup row>
          {options.map((option: any, index: number) => {
            const optionPath = Paths.compose(path, `${index}`);
            const checkboxValue = data?.includes(option.value)
              ? option.value
              : undefined;
            return (
              <FormControlLabel
                id={option.value}
                key={option.value}
                control={
                  <MuiCheckbox
                    key={'checkbox-' + option.value}
                    isValid={isEmpty(errors)}
                    path={optionPath}
                    handleChange={(_childPath, newValue) =>
                      newValue
                        ? addItem(path, option.value)
                        : removeItem(path, option.value)
                    }
                    data={checkboxValue}
                    errors={errors}
                    schema={schema}
                    visible={visible}
                    {...otherProps}
                  />
                }
                label={option.label}
              />
            );
          })}
        </FormGroup>
        <FormHelperText error>
          {errors}
        </FormHelperText>
      </FormControl>
    </Hidden>

In the first case of Hidden I’m not sure it’s really usefull to preserve the actual behavior: MUI support perfectly SSR. And the actual beavior could easily reproduced by the end user.

For the second case Hidden, I really did not understand why the field should be hidden on XL screen an up… Maybe you have an explanation? Or is it a typo ?