commons.ts 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. import { DevidedPagePath, Lang } from '@growi/core';
  2. import { GetServerSideProps, GetServerSidePropsContext } from 'next';
  3. import { SSRConfig, UserConfig } from 'next-i18next';
  4. import * as nextI18NextConfig from '^/config/next-i18next.config';
  5. import { CrowiRequest } from '~/interfaces/crowi-request';
  6. import { GrowiThemes } from '~/interfaces/theme';
  7. export type CommonProps = {
  8. namespacesRequired: string[], // i18next
  9. currentPathname: string,
  10. appTitle: string,
  11. siteUrl: string,
  12. confidential: string,
  13. theme: GrowiThemes,
  14. customTitleTemplate: string,
  15. csrfToken: string,
  16. growiVersion: string,
  17. } & Partial<SSRConfig>;
  18. // eslint-disable-next-line max-len
  19. export const getServerSideCommonProps: GetServerSideProps<CommonProps> = async(context: GetServerSidePropsContext) => {
  20. const req: CrowiRequest = context.req as CrowiRequest;
  21. const { crowi } = req;
  22. const {
  23. appService, configManager, customizeService,
  24. } = crowi;
  25. const url = new URL(context.resolvedUrl, 'http://example.com');
  26. const currentPathname = decodeURI(url.pathname);
  27. const props: CommonProps = {
  28. namespacesRequired: ['translation'],
  29. currentPathname,
  30. appTitle: appService.getAppTitle(),
  31. siteUrl: appService.getSiteUrl(),
  32. confidential: appService.getAppConfidential() || '',
  33. theme: configManager.getConfig('crowi', 'customize:theme'),
  34. customTitleTemplate: customizeService.customTitleTemplate,
  35. csrfToken: req.csrfToken(),
  36. growiVersion: crowi.version,
  37. };
  38. return { props };
  39. };
  40. export const getNextI18NextConfig = async(
  41. // 'serverSideTranslations' method should be given from Next.js Page
  42. // because importing it in this file causes https://github.com/isaachinman/next-i18next/issues/1545
  43. serverSideTranslations: (initialLocale: string, namespacesRequired?: string[] | undefined, configOverride?: UserConfig | null) => Promise<SSRConfig>,
  44. context: GetServerSidePropsContext, namespacesRequired?: string[] | undefined,
  45. ): Promise<SSRConfig> => {
  46. const req: CrowiRequest = context.req as CrowiRequest;
  47. const { crowi, user } = req;
  48. const { configManager } = crowi;
  49. // determine language
  50. const locale = user?.lang
  51. ?? configManager.getConfig('crowi', 'app:globalLang') as Lang
  52. ?? Lang.en_US;
  53. return serverSideTranslations(locale, namespacesRequired ?? ['translation'], nextI18NextConfig);
  54. };
  55. /**
  56. * Generate whole title string for the specified title
  57. * @param props
  58. * @param title
  59. */
  60. export const useCustomTitle = (props: CommonProps, title: string): string => {
  61. return props.customTitleTemplate
  62. .replace('{{sitename}}', props.appTitle)
  63. .replace('{{page}}', title)
  64. .replace('{{pagepath}}', title)
  65. .replace('{{pagename}}', title);
  66. };
  67. /**
  68. * Generate whole title string for the specified page path
  69. * @param props
  70. * @param pagePath
  71. */
  72. export const useCustomTitleForPage = (props: CommonProps, pagePath: string): string => {
  73. const dPagePath = new DevidedPagePath(pagePath, true, true);
  74. return props.customTitleTemplate
  75. .replace('{{sitename}}', props.appTitle)
  76. .replace('{{pagepath}}', pagePath)
  77. .replace('{{page}}', dPagePath.latter) // for backward compatibility
  78. .replace('{{pagename}}', dPagePath.latter);
  79. };