-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathgetEventsStaticProps.ts
More file actions
116 lines (105 loc) · 3.7 KB
/
Copy pathgetEventsStaticProps.ts
File metadata and controls
116 lines (105 loc) · 3.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import type {
ApolloClient,
NormalizedCacheObject,
} from '@apollo/client/core/index.js';
import { MenuDocument } from '@city-of-helsinki/react-helsinki-headless-cms/apollo';
import type { Menu, Language } from '@events-helsinki/components';
import {
DEFAULT_FOOTER_MENU_NAME,
DEFAULT_HEADER_MENU_NAME,
HARDCODED_LANGUAGES,
getLanguageOrDefault,
DEFAULT_HEADER_UNIVERSAL_BAR_MENU_NAME,
} from '@events-helsinki/components';
import type { GetStaticPropsContext, GetStaticPropsResult } from 'next';
import { staticGenerationLogger } from '../../logger';
import initializeEventsApolloClient from '../clients/eventsApolloClient';
import AppConfig from './AppConfig';
type EventsContext = {
apolloClient: ApolloClient<NormalizedCacheObject>;
};
export type EventsGlobalPageProps<P = Record<string, unknown>> = {
initialApolloState: NormalizedCacheObject;
} & Promise<GetStaticPropsResult<P>>;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export default async function getEventsStaticProps<P = Record<string, any>>(
context: GetStaticPropsContext,
tryToGetPageProps: (
eventsContext: EventsContext
) => Promise<GetStaticPropsResult<P>>
) {
const language = getLanguageOrDefault(context.locale);
const apolloClient = initializeEventsApolloClient();
try {
const globalCmsData = await getGlobalCMSData({
client: apolloClient,
context,
});
const result = await tryToGetPageProps({ apolloClient });
const props =
'props' in result
? {
initialApolloState: apolloClient.cache.extract(),
locale: language,
...globalCmsData,
...result.props,
}
: undefined;
return {
// Apply revalidate, allow it to be overwritten
revalidate: AppConfig.defaultRevalidate,
...result,
props,
};
} catch (e: unknown) {
// Generic error handling
staticGenerationLogger.error(
`Error while generating a page (with locale "${context.locale}"):`,
e
);
// Throw an error, because otherwise the NextJS generates a page that is always somehow broken:
// The biggest issue here is with the translations: https://github.com/i18next/next-i18next/issues/1020.
// The i18next instance is not ready to process translations when nextjs tries to render the error page.
// When an error is thrown, the page regeneration is abandoned on errors,
// so the last successful generation will stay in use in action!
throw e;
}
}
type GetGlobalCMSDataParams = {
client: ApolloClient<NormalizedCacheObject>;
context: GetStaticPropsContext;
};
type ReturnedGlobalCMSData = {
headerMenu?: Menu;
headerUniversalBarMenu?: Menu;
footerMenu?: Menu;
languages?: Language[];
};
const getMenu = async (
menuName: string,
client: GetGlobalCMSDataParams['client']
): Promise<Menu | undefined> =>
(
await client.query({
query: MenuDocument,
variables: { id: menuName, menuIdentifiersOnly: true },
fetchPolicy: 'network-only', // Always fetch new, but update the cache.
})
)?.data?.menu;
// Get CMS data that's required on every page
async function getGlobalCMSData({
client,
context,
}: GetGlobalCMSDataParams): Promise<ReturnedGlobalCMSData> {
const language = getLanguageOrDefault(context.locale);
const headerMenuName = DEFAULT_HEADER_MENU_NAME[language];
const headerUniversalBarMenuName =
DEFAULT_HEADER_UNIVERSAL_BAR_MENU_NAME[language];
const footerMenuName = DEFAULT_FOOTER_MENU_NAME[language];
return {
headerMenu: await getMenu(headerMenuName, client),
headerUniversalBarMenu: await getMenu(headerUniversalBarMenuName, client),
footerMenu: await getMenu(footerMenuName, client),
languages: HARDCODED_LANGUAGES,
};
}