'How to format time in React SSR rendered page using client time zone?

I'm building a website with React and recently switched to using server-side rendering (SSR) for improved performance. One issue I ran into after this change is that when I format a time on the page (I'm using Moment.js) it renders incorrectly using the server's time zone.

How can I format the time using the client's time zone? Do I need to leave the time off on the server response and have the client render that afterwards?



Solution 1:[1]

Do I need to leave the time off on the server response and have the client render that afterwards?

Unfortunately yes.

You can build a utility component to make this less tedious.

Class component:

// utility
import React, { Component } from 'react';

// Class component
export default class ClientRender extends Component {
  state = { isMounted: false };
  
  componentDidMount () {
    this.setState({ isMounted: true });
  }

  render () {
    const { children } = this.props;
    const { isMounted } = this.state;
    
    return isMounted ? children : null;
  }
}

// Function component
export default function ClientRender({ children }) {
  const [isMounted, setIsMounted] = React.useState(false);

  React.useEffect(() => {
    setIsMounted(true);
  }, []);

  return isMounted ? children : null;
}

// in your app
import React from 'react';
import moment from 'moment';

import ClientRender from './path/to/client-render';

export default function MyComponent (props) {
  return (
    <div>
      <ClientRender>{moment(props.timeUTC * 1000).format('LLL')}</ClientRender>
    </div>
  );
}

Solution 2:[2]

I haven't done this with React, specifically, but the general approach is to render a <time> element (documentation here) with a full date/time format that contains the timezone, then adjust the text output client-side.

This should be fairly straightforward when you rehydrate client-side; react-moment also accepts a timezone if you're rendering server-side per request… 

Solution 3:[3]

I have the same issue.

One thing that you may try is to set a cookie client-side with the timezone as value.

The first visit of a client will always be an issue so be prepared to use a default timezone or delay rendering (with didMount event).

But once a client comes back with said cookie you can use that cookie value as the timezone for date and time string rendering.

Not tried it yet, I will try to think about updating that post if I'm successful

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mayank Chauhan
Solution 2 coreyward
Solution 3 Apolo