Răsfoiți Sursa

Refactor routing type handling: replace isNextjsRoutingTypeInitial with nextjsRoutingType for consistency across components

Yuki Takei 2 luni în urmă
părinte
comite
dcf719a508

+ 9 - 18
apps/app/src/pages/[[...path]]/index.page.tsx

@@ -36,10 +36,7 @@ import { getServerSideCommonEachProps } from '../common-props';
 import { useInitialCSRFetch } from '../general-page';
 import { useHydrateGeneralPageConfigurationAtoms } from '../general-page/hydrate';
 import { registerPageToShowRevisionWithMeta } from '../general-page/superjson';
-import {
-  detectNextjsRoutingType,
-  NextjsRoutingType,
-} from '../utils/nextjs-routing-utils';
+import { NextjsRoutingType } from '../utils/nextjs-routing-utils';
 import { useCustomTitleForPage } from '../utils/page-title-customization';
 import { mergeGetServerSidePropsResults } from '../utils/server-side-props';
 import { NEXT_JS_ROUTING_PAGE } from './consts';
@@ -96,11 +93,8 @@ const EditablePageEffects = dynamic(
 
 type Props = EachProps | InitialProps;
 
-const isInitialProps = (props: Props): props is InitialProps => {
-  return (
-    'isNextjsRoutingTypeInitial' in props && props.isNextjsRoutingTypeInitial
-  );
-};
+const isInitialProps = (props: Props): props is InitialProps =>
+  props.nextjsRoutingType === NextjsRoutingType.INITIAL;
 
 const Page: NextPageWithLayout<Props> = (props: Props) => {
   // Initialize Jotai atoms with initial data - must be called unconditionally
@@ -130,8 +124,11 @@ const Page: NextPageWithLayout<Props> = (props: Props) => {
   useSameRouteNavigation();
   useShallowRouting(props);
 
-  // If initial props and skipSSR, fetch page data on client-side
-  useInitialCSRFetch(isInitialProps(props) && props.skipSSR);
+  // Fetch page data on client-side
+  useInitialCSRFetch({
+    nextjsRoutingType: props.nextjsRoutingType,
+    skipSSR: isInitialProps(props) ? props.skipSSR : false,
+  });
 
   useEffect(() => {
     // Initialize editing markdown only when page path changes
@@ -269,16 +266,10 @@ export const getServerSideProps: GetServerSideProps<Props> = async (
   // STAGE 2
   //
 
-  // detect Next.js routing type
-  const nextjsRoutingType = detectNextjsRoutingType(
-    context,
-    NEXT_JS_ROUTING_PAGE,
-  );
-
   // Merge all results in a type-safe manner (using sequential merging)
   return mergeGetServerSidePropsResults(
     commonEachPropsResult,
-    nextjsRoutingType === NextjsRoutingType.SAME_ROUTE
+    commonEachProps.nextjsRoutingType === NextjsRoutingType.SAME_ROUTE
       ? await getServerSidePropsForSameRoute(context)
       : await getServerSidePropsForInitial(context),
   );

+ 10 - 3
apps/app/src/pages/common-props/commons.ts

@@ -6,10 +6,15 @@ import type { CrowiRequest } from '~/interfaces/crowi-request';
 import { getGrowiVersion } from '~/utils/growi-version';
 import loggerFactory from '~/utils/logger';
 
+import {
+  detectNextjsRoutingType,
+  NextjsRoutingType,
+} from '../utils/nextjs-routing-utils';
+
 const logger = loggerFactory('growi:pages:common-props:commons');
 
 export type CommonInitialProps = {
-  isNextjsRoutingTypeInitial: true;
+  nextjsRoutingType: typeof NextjsRoutingType.INITIAL;
   appTitle: string;
   siteUrl: string | undefined;
   siteUrlWithEmptyValueWarn: string;
@@ -43,7 +48,7 @@ export const getServerSideCommonInitialProps: GetServerSideProps<
 
   return {
     props: {
-      isNextjsRoutingTypeInitial: true,
+      nextjsRoutingType: NextjsRoutingType.INITIAL,
       appTitle: appService.getAppTitle(),
       siteUrl: configManager.getConfig('app:siteUrl'),
       siteUrlWithEmptyValueWarn: growiInfoService.getSiteUrl(),
@@ -83,6 +88,7 @@ export const isCommonInitialProps = (
 };
 
 export type CommonEachProps = {
+  nextjsRoutingType: NextjsRoutingType;
   currentPathname: string;
   nextjsRoutingPage?: string; // must be set by each page
   currentUser?: IUserHasId;
@@ -179,12 +185,13 @@ export const getServerSideCommonEachProps = async (
   }
 
   const props = {
+    nextjsRoutingType: detectNextjsRoutingType(context, nextjsRoutingPage),
     currentPathname,
     nextjsRoutingPage,
     currentUser,
     isMaintenanceMode,
     redirectDestination,
-  };
+  } satisfies CommonEachProps;
 
   const shouldContainNextjsRoutingPage = nextjsRoutingPage != null;
   if (!isValidCommonEachRouteProps(props, shouldContainNextjsRoutingPage)) {

+ 4 - 3
apps/app/src/pages/general-page/type-guards.ts

@@ -2,6 +2,7 @@ import { isIPageInfo } from '@growi/core/dist/interfaces';
 
 import loggerFactory from '~/utils/logger';
 
+import { NextjsRoutingType } from '../utils/nextjs-routing-utils';
 import type { GeneralPageInitialProps } from './types';
 
 const logger = loggerFactory('growi:pages:general-page:type-guards');
@@ -17,10 +18,10 @@ export function isValidGeneralPageInitialProps(
 
   // Then validate GeneralPageInitialProps-specific properties
   // CommonPageInitialProps
-  if (p.isNextjsRoutingTypeInitial !== true) {
+  if (p.nextjsRoutingType !== NextjsRoutingType.INITIAL) {
     logger.warn(
-      'isValidGeneralPageInitialProps: isNextjsRoutingTypeInitial is not true',
-      { isNextjsRoutingTypeInitial: p.isNextjsRoutingTypeInitial },
+      'isValidGeneralPageInitialProps: nextjsRoutingType does not equal to NextjsRoutingType.INITIAL',
+      { nextjsRoutingType: p.nextjsRoutingType },
     );
     return false;
   }

+ 14 - 4
apps/app/src/pages/general-page/use-initial-skip-ssr-fetch.ts

@@ -2,16 +2,26 @@ import { useEffect } from 'react';
 
 import { useFetchCurrentPage } from '~/states/page';
 
+import { NextjsRoutingType } from '../utils/nextjs-routing-utils';
+
 /**
  * useInitialCSRFetch
  *
- * Fetches current page data on client-side if shouldFetch === true
- *
- * @param shouldFetch - Whether SSR is skipped (from props)
+ * Fetches current page data on client-side by conditionally
  */
-export const useInitialCSRFetch = (shouldFetch?: boolean): void => {
+export const useInitialCSRFetch = (condition: {
+  nextjsRoutingType: NextjsRoutingType;
+  skipSSR?: boolean;
+}): void => {
   const { fetchCurrentPage } = useFetchCurrentPage();
 
+  // Should fetch page data on client-side or not
+  const shouldFetch =
+    condition.nextjsRoutingType === NextjsRoutingType.FROM_OUTSIDE ||
+    condition.skipSSR;
+
+  // Note: When the nextjsRoutingType is SAME_ROUTE, the data fetching is handled by useSameRouteNavigation
+
   useEffect(() => {
     if (shouldFetch) {
       fetchCurrentPage({ force: true });

+ 10 - 17
apps/app/src/pages/share/[[...path]]/index.page.tsx

@@ -9,10 +9,7 @@ import { DrawioViewerScript } from '~/components/Script/DrawioViewerScript';
 import { ShareLinkPageView } from '~/components/ShareLinkPageView';
 import type { CommonEachProps } from '~/pages/common-props';
 import { getServerSideCommonEachProps } from '~/pages/common-props';
-import {
-  detectNextjsRoutingType,
-  NextjsRoutingType,
-} from '~/pages/utils/nextjs-routing-utils';
+import { NextjsRoutingType } from '~/pages/utils/nextjs-routing-utils';
 import { useCustomTitleForPage } from '~/pages/utils/page-title-customization';
 import { mergeGetServerSidePropsResults } from '~/pages/utils/server-side-props';
 import { useCurrentPageData, useCurrentPagePath } from '~/states/page';
@@ -41,11 +38,8 @@ const GrowiContextualSubNavigation = dynamic(
 
 type Props = CommonEachProps | InitialProps;
 
-const isInitialProps = (props: Props): props is InitialProps => {
-  return (
-    'isNextjsRoutingTypeInitial' in props && props.isNextjsRoutingTypeInitial
-  );
-};
+const isInitialProps = (props: Props): props is InitialProps =>
+  props.nextjsRoutingType === NextjsRoutingType.INITIAL;
 
 const SharedPage: NextPageWithLayout<Props> = (props: Props) => {
   // Initialize Jotai atoms with initial data - must be called unconditionally
@@ -66,8 +60,11 @@ const SharedPage: NextPageWithLayout<Props> = (props: Props) => {
   // Use custom hooks for navigation and routing
   // useSameRouteNavigation();
 
-  // If initial props and skipSSR, fetch page data on client-side
-  useInitialCSRFetch(isInitialProps(props) && props.skipSSR);
+  // Fetch page data on client-side
+  useInitialCSRFetch({
+    nextjsRoutingType: props.nextjsRoutingType,
+    skipSSR: isInitialProps(props) ? props.skipSSR : false,
+  });
 
   // If the data on the page changes without router.push, pageWithMeta remains old because getServerSideProps() is not executed
   // So preferentially take page data from useSWRxCurrentPage
@@ -162,16 +159,12 @@ export const getServerSideProps: GetServerSideProps<Props> = async (
   // STAGE 2
   //
 
-  // detect Next.js routing type
-  const nextjsRoutingType = detectNextjsRoutingType(
-    context,
-    NEXT_JS_ROUTING_PAGE,
-  );
+  const commonEachProps = await commonEachPropsResult.props;
 
   // Merge all results in a type-safe manner (using sequential merging)
   return mergeGetServerSidePropsResults(
     commonEachPropsResult,
-    nextjsRoutingType === NextjsRoutingType.INITIAL
+    commonEachProps.nextjsRoutingType === NextjsRoutingType.INITIAL
       ? await getServerSidePropsForInitial(context)
       : emptyProps,
   );