Add server-side hydration of initial config+status. Closes #1964
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
/* eslint-disable react/no-danger */
|
||||
/* eslint-disable react/no-unescaped-entities */
|
||||
import { Layout } from 'antd';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import Head from 'next/head';
|
||||
@@ -27,6 +29,11 @@ export const Main: FC = () => {
|
||||
setupNoLinkReferrer(layoutRef.current);
|
||||
}, []);
|
||||
|
||||
const hydrationScript = `
|
||||
window.statusHydration = {{.StatusJSON}};
|
||||
window.configHydration = {{.ServerConfigJSON}};
|
||||
`;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
@@ -86,6 +93,7 @@ export const Main: FC = () => {
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
|
||||
<style>{customStyles}</style>
|
||||
<script dangerouslySetInnerHTML={{ __html: hydrationScript }} />
|
||||
</Head>
|
||||
|
||||
<ClientConfigStore />
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useEffect } from 'react';
|
||||
import { FC, useEffect } from 'react';
|
||||
import { atom, selector, useRecoilState, useSetRecoilState } from 'recoil';
|
||||
import { useMachine } from '@xstate/react';
|
||||
import { makeEmptyClientConfig, ClientConfig } from '../../interfaces/client-config.model';
|
||||
@@ -170,7 +170,7 @@ function mergeMeta(meta) {
|
||||
}, {});
|
||||
}
|
||||
|
||||
export const ClientConfigStore = () => {
|
||||
export const ClientConfigStore: FC = () => {
|
||||
const [appState, appStateSend, appStateService] = useMachine(appStateModel);
|
||||
|
||||
const setChatDisplayName = useSetRecoilState<string>(chatDisplayNameAtom);
|
||||
@@ -343,6 +343,29 @@ export const ClientConfigStore = () => {
|
||||
}
|
||||
};
|
||||
|
||||
// Read the config and status on initial load from a JSON string that lives
|
||||
// in window. This is placed there server-side and allows for fast initial
|
||||
// load times because we don't have to wait for the API calls to complete.
|
||||
useEffect(() => {
|
||||
try {
|
||||
if ((window as any).configHydration) {
|
||||
const config = JSON.parse((window as any).configHydration);
|
||||
setClientConfig(config);
|
||||
}
|
||||
} catch (e) {
|
||||
// console.error('Error parsing config hydration', e);
|
||||
}
|
||||
|
||||
try {
|
||||
if ((window as any).statusHydration) {
|
||||
const status = JSON.parse((window as any).statusHydration);
|
||||
setServerStatus(status);
|
||||
}
|
||||
} catch (e) {
|
||||
// console.error('error parsing status hydration', e);
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
updateClientConfig();
|
||||
handleUserRegistration();
|
||||
|
||||
Reference in New Issue
Block a user