ReferenceError: Cannot access 'globalVariants' before initialization

I am getting this error message

PLASMIC: Encountered error when pre-rendering PlasmicUsSearch: ReferenceError: Cannot access ‘globalVariants’ before initialization

For my following code in Page app using Plasmic Codegen.

import * as React from "react";
import { GetStaticProps, GetStaticPaths } from "next";
import { extractPlasmicQueryData } from "@plasmicapp/react-web/lib/prepass";
import { PlasmicQueryDataProvider } from "@plasmicapp/react-web/lib/query";
import { PageParamsProvider as PageParamsProvider__ } from "@plasmicapp/react-web/lib/host";

import GlobalContextsProvider from "../../../components/plasmic/chapter_3/PlasmicGlobalContextsProvider";
import { PlasmicUsSearch } from "../../../components/plasmic/chapter_3/PlasmicUsSearch";
import { DataProvider } from "@plasmicapp/react-web/lib/host";

/** Fields we want to hide from __NEXT_DATA__ */
const SENSITIVE_FIELDS = [
  "food_drink_id",
  "food_drink_slug",
  "premises_name",
  "premises_address",
  "latitude",
  "longitude",
  "geo_location",
];

function stripFields(obj: Record<string, any>) {
  const cleaned: Record<string, any> = {};
  for (const key in obj) {
    if (!SENSITIVE_FIELDS.includes(key)) {
      cleaned[key] = obj[key];
    }
  }
  return cleaned;
}

function filterQueryCache(queryCache: Record<string, any>) {
  const filteredCache: Record<string, any> = {};
  for (const key in queryCache) {
    const entry = queryCache[key];
    if (entry && typeof entry === "object") {
      let newEntry = { ...entry };
      if (Array.isArray(entry.data)) {
        newEntry.data = entry.data.map((section: any) => {
          if (section && !Array.isArray(section)) {
            return stripFields(section);
          }
          if (section?.data && Array.isArray(section.data)) {
            return {
              ...section,
              data: section.data.map((item: Record<string, any>) =>
                stripFields(item)
              ),
            };
          }
          return section;
        });
      }
      if (entry.schema?.fields) {
        newEntry.schema = {
          ...entry.schema,
          fields: entry.schema.fields.filter(
            (f: any) => !SENSITIVE_FIELDS.includes(f.id)
          ),
        };
      }
      filteredCache[key] = newEntry;
    } else {
      filteredCache[key] = entry;
    }
  }
  return filteredCache;
}

function isQueryCacheEmpty(queryCache: Record<string, any>): boolean {
  return Object.values(queryCache).every((entry: any) => {
    if (!entry) return true;
    if (Array.isArray(entry?.data)) return entry.data.length === 0;
    return false;
  });
}

export const getStaticPaths: GetStaticPaths = async () => ({
  paths: [],
  fallback: "blocking",
});

export const getStaticProps: GetStaticProps = async (context) => {
  let search_text_param = context.params?.search_text;

  const search_text = Array.isArray(search_text_param)
    ? search_text_param.join(" ")
    : (search_text_param ?? "");

  // Always a defined string, may be "" → random fallback
  const safe_search_text = search_text.trim();

  const element = (
    <PageParamsProvider__
      route="/us/search/[[...search_text]]"
      params={{ search_text: safe_search_text }}
      query={{ search_text: safe_search_text }}
    >
      <DataProvider
        name="userCurrentLocation"
        data={{ latitude: null, longitude: null, permission: false }}
      >
        <PlasmicUsSearch />
      </DataProvider>
    </PageParamsProvider__>
  );

  let queryCache: Record<string, any> = {};
  try {
    queryCache = await extractPlasmicQueryData(element);
  } catch (err: any) {
    if (
      err instanceof ReferenceError &&
      /globalVariants/.test(err.message)
    ) {
      console.warn("⚠️ Ignoring globalVariants init error during SSR prepass");
      queryCache = {}; // client will hydrate later
    } else {
      throw err;
    }
  }

  if (isQueryCacheEmpty(queryCache)) {
    return { notFound: true };
  }

  const safeCache = filterQueryCache(queryCache);

  return {
    props: {
      queryCache: safeCache,
      search_text: safe_search_text,
    },
    revalidate: 60,
  };
};

export default function UsSearch({
  queryCache,
  search_text,
}: {
  queryCache: any;
  search_text: string;
}) {
  return (
    <PlasmicQueryDataProvider prefetchedCache={queryCache}>
      <GlobalContextsProvider>
        <PageParamsProvider__
          route="/us/search/[[...search_text]]"
          params={{ search_text }}
          query={{ search_text }}
        >
          <DataProvider
            name="userCurrentLocation"
            data={{ latitude: null, longitude: null, permission: false }}
          >
            <PlasmicUsSearch />
          </DataProvider>
        </PageParamsProvider__>
      </GlobalContextsProvider>
    </PlasmicQueryDataProvider>
  );
}

ChatGPT reasoned the following snippet from plasmic generated file - PlasmicUsSearch, cuasing the error as followed:

const stateSpecs: Parameters<typeof useDollarState>[0] = React.useMemo(
  () => [
    {
      path: "us.footerNavigatorOnClickButtonNavBar",
      initFunc: ({ $props, $state, $queries, $ctx }) =>
        hasVariant(globalVariants, "screen", "mobileOnly")
          ? { Home: true, Location: false, Search: false }
          : { Home: true, Location: false, Search: false }
    }
  ],
  [$props, $ctx, $refs]
);

...

const globalVariants = _useGlobalVariants();

Here’s the key problem:

The closure for initFunc is created before const globalVariants = … runs.

During SSR prepass (extractPlasmicQueryData), React eagerly evaluates those initFuncs → tries to access globalVariants before it exists → boom.

Please advise.

Thank you.

@mouthains hi!
Are you trying to use globalVariants in the component? It’s a bit hard to follow what’s happening in the code, because it seems that some parts are omitted

Btw, you can use code format in messages, it would be easier for us to read the code, just type it as ```tsx and then three ` on the end line to create the code block, which will save all the indentation on paste

Simply I am just doing SSR for my page with the code as shown (My apology for not separating the code from the text).

@mouthains, can you please also send the code for the PlasmicUsSearch component?
I also have a few questions:

  1. how do you get the value for the globalContext? Where do you import _useGlobalVariants from?
  2. Are you using app router or the pages router?
  3. Can you move the const globalVariants = _useGlobalVariants(); line to the beginning of the component, before the const stateSpecs:, to make sure the hooks get executed in the correct order?

This the complete code for PlasmicUsSearch which I believe is auto-generated by Plasmic.

/* eslint-disable */
/* tslint:disable */
// @ts-nocheck
/* prettier-ignore-start */

/** @jsxRuntime classic */
/** @jsx createPlasmicElementProxy */
/** @jsxFrag React.Fragment */

// This class is auto-generated by Plasmic; please do not edit!
// Plasmic Project: rSNJxoyWcY3xfv1fFT5emw
// Component: NWVymX3ngugv

import * as React from "react";

import Head from "next/head";
import Link, { LinkProps } from "next/link";
import { useRouter } from "next/router";

import {
  Flex as Flex__,
  MultiChoiceArg,
  PlasmicDataSourceContextProvider as PlasmicDataSourceContextProvider__,
  PlasmicIcon as PlasmicIcon__,
  PlasmicImg as PlasmicImg__,
  PlasmicLink as PlasmicLink__,
  PlasmicPageGuard as PlasmicPageGuard__,
  SingleBooleanChoiceArg,
  SingleChoiceArg,
  Stack as Stack__,
  StrictProps,
  Trans as Trans__,
  classNames,
  createPlasmicElementProxy,
  deriveRenderOpts,
  ensureGlobalVariants,
  generateOnMutateForSpec,
  generateStateOnChangeProp,
  generateStateOnChangePropForCodeComponents,
  generateStateValueProp,
  get as $stateGet,
  hasVariant,
  initializeCodeComponentStates,
  initializePlasmicStates,
  makeFragment,
  omit,
  pick,
  renderPlasmicSlot,
  set as $stateSet,
  useCurrentUser,
  useDollarState,
  usePlasmicTranslator,
  useTrigger,
  wrapWithClassName
} from "@plasmicapp/react-web";
import {
  DataCtxReader as DataCtxReader__,
  useDataEnv,
  useGlobalActions
} from "@plasmicapp/react-web/lib/host";

import {
  executePlasmicDataOp,
  usePlasmicDataOp,
  usePlasmicInvalidate
} from "@plasmicapp/react-web/lib/data-sources";

import TemplateCountry from "../../TemplateCountry"; // plasmic-import: _BhWob1gF6zV/component
import { Fetcher } from "@plasmicapp/react-web/lib/data-sources";
import { _useGlobalVariants } from "./plasmic"; // plasmic-import: rSNJxoyWcY3xfv1fFT5emw/projectModule
import { _useStyleTokens } from "./PlasmicStyleTokensProvider"; // plasmic-import: rSNJxoyWcY3xfv1fFT5emw/styleTokensProvider
import { _useStyleTokens as useStyleTokens_antd_5_hostless } from "../antd_5_hostless/PlasmicStyleTokensProvider"; // plasmic-import: ohDidvG9XsCeFumugENU3J/styleTokensProvider
import { _useStyleTokens as useStyleTokens_plasmic_rich_components } from "../plasmic_rich_components/PlasmicStyleTokensProvider"; // plasmic-import: jkU633o1Cz7HrJdwdxhVHk/styleTokensProvider

import "@plasmicapp/react-web/lib/plasmic.css";

import projectcss from "./plasmic.module.css"; // plasmic-import: rSNJxoyWcY3xfv1fFT5emw/projectcss
import sty from "./PlasmicUsSearch.module.css"; // plasmic-import: NWVymX3ngugv/css

createPlasmicElementProxy;

export type PlasmicUsSearch__VariantMembers = {};
export type PlasmicUsSearch__VariantsArgs = {};
type VariantPropType = keyof PlasmicUsSearch__VariantsArgs;
export const PlasmicUsSearch__VariantProps = new Array<VariantPropType>();

export type PlasmicUsSearch__ArgsType = {};
type ArgPropType = keyof PlasmicUsSearch__ArgsType;
export const PlasmicUsSearch__ArgProps = new Array<ArgPropType>();

export type PlasmicUsSearch__OverridesType = {
  root?: Flex__<"div">;
  us?: Flex__<typeof TemplateCountry>;
};

export interface DefaultUsSearchProps {}

const $$ = {};

function useNextRouter() {
  try {
    return useRouter();
  } catch {}
  return undefined;
}

function PlasmicUsSearch__RenderFunc(props: {
  variants: PlasmicUsSearch__VariantsArgs;
  args: PlasmicUsSearch__ArgsType;
  overrides: PlasmicUsSearch__OverridesType;
  forNode?: string;
}) {
  const { variants, overrides, forNode } = props;

  const args = React.useMemo(
    () =>
      Object.assign(
        {},
        Object.fromEntries(
          Object.entries(props.args).filter(([_, v]) => v !== undefined)
        )
      ),
    [props.args]
  );

  const $props = {
    ...args,
    ...variants
  };

  const __nextRouter = useNextRouter();

  const $ctx = useDataEnv?.() || {};
  const refsRef = React.useRef({});
  const $refs = refsRef.current;

  const $globalActions = useGlobalActions?.();
  const globalVariants = _useGlobalVariants();  /** move from bottom to up */

  let [$queries, setDollarQueries] = React.useState<
    Record<string, ReturnType<typeof usePlasmicDataOp>>
  >({});
  const stateSpecs: Parameters<typeof useDollarState>[0] = React.useMemo(
    () => [
      {
        path: "us.headerSearchBarValue",
        type: "private",
        variableType: "text",
        initFunc: ({ $props, $state, $queries, $ctx }) =>
          (() => {
            try {
              return (() => {
                function fromSlug(slug) {
                  return (slug ?? "")
                    .toString()
                    .replace(/-/g, " ")
                    .replace(/\s+/g, " ")
                    .trim();
                }
                return fromSlug($ctx?.params?.search_text);
              })();
            } catch (e) {
              if (
                e instanceof TypeError ||
                e?.plasmicType === "PlasmicUndefinedDataError"
              ) {
                return undefined;
              }
              throw e;
            }
          })()
      },
      {
        path: "us.footerNavigatorTextboxValue",
        type: "private",
        variableType: "text",
        initFunc: ({ $props, $state, $queries, $ctx }) => undefined
      },
      {
        path: "searchText",
        type: "private",
        variableType: "text",
        initFunc: ({ $props, $state, $queries, $ctx }) => " "
      },
      {
        path: "us.headerSearchButtonSearchDisable",
        type: "private",
        variableType: "boolean",
        initFunc: ({ $props, $state, $queries, $ctx }) =>
          (() => {
            try {
              return (
                $state.us.headerSearchBarValue == null ||
                $state.us.headerSearchBarValue.trim() === ""
              );
            } catch (e) {
              if (
                e instanceof TypeError ||
                e?.plasmicType === "PlasmicUndefinedDataError"
              ) {
                return undefined;
              }
              throw e;
            }
          })()
      },
      {
        path: "us.headerSearchButtonNearMeDisable",
        type: "private",
        variableType: "boolean",
        initFunc: ({ $props, $state, $queries, $ctx }) => false
      },
      {
        path: "us.footerNavigatorOnClickButtonNavBar",
        type: "private",
        variableType: "object",
        initFunc: ({ $props, $state, $queries, $ctx }) =>
          hasVariant(globalVariants, "screen", "mobileOnly")
            ? { Home: true, Location: false, Search: false }
            : { Home: true, Location: false, Search: false }
      }
    ],
    [$props, $ctx, $refs]
  );
  const $state = useDollarState(stateSpecs, {
    $props,
    $ctx,
    $queries: $queries,
    $refs
  });

  const new$Queries: Record<string, ReturnType<typeof usePlasmicDataOp>> = {
    eatdrinkDataUs: usePlasmicDataOp(() => {
      return {
        sourceId: "ue8rsHfrjwXahV7YQg8XKk",
        opId: "80ba97fe-cc0e-495e-bf13-3a9fb0a05f7c",
        userArgs: {
          query: [
            $ctx.params.search_text,

            $ctx.userCurrentLocation.latitude,

            $ctx.userCurrentLocation.longitude
          ]
        },
        cacheKey: `plasmic.$.${(() => {
          try {
            return undefined;
          } catch (e) {
            if (
              e instanceof TypeError ||
              e?.plasmicType === "PlasmicUndefinedDataError"
            ) {
              return "";
            }
            throw e;
          }
        })()}.$.80ba97fe-cc0e-495e-bf13-3a9fb0a05f7c.$.`,
        invalidatedKeys: null,
        roleId: null
      };
    })
  };
  if (Object.keys(new$Queries).some(k => new$Queries[k] !== $queries[k])) {
    setDollarQueries(new$Queries);

    $queries = new$Queries;
  }

  //const globalVariants = _useGlobalVariants();
  const styleTokensClassNames = _useStyleTokens();
  const styleTokensClassNames_antd_5_hostless =
    useStyleTokens_antd_5_hostless();
  const styleTokensClassNames_plasmic_rich_components =
    useStyleTokens_plasmic_rich_components();

  return (
    <React.Fragment>
      <Head>
        <meta name="twitter:card" content="summary_large_image" />
        <title key="title">{PlasmicUsSearch.pageMetadata.title}</title>
        <meta
          key="og:title"
          property="og:title"
          content={PlasmicUsSearch.pageMetadata.title}
        />
        <meta
          key="twitter:title"
          name="twitter:title"
          content={PlasmicUsSearch.pageMetadata.title}
        />
        <meta
          key="description"
          name="description"
          content={PlasmicUsSearch.pageMetadata.description}
        />
        <meta
          key="og:description"
          property="og:description"
          content={PlasmicUsSearch.pageMetadata.description}
        />
        <meta
          key="twitter:description"
          name="twitter:description"
          content={PlasmicUsSearch.pageMetadata.description}
        />
        <meta
          key="og:image"
          property="og:image"
          content={PlasmicUsSearch.pageMetadata.ogImageSrc}
        />
        <meta
          key="twitter:image"
          name="twitter:image"
          content={PlasmicUsSearch.pageMetadata.ogImageSrc}
        />
        <link rel="canonical" href={PlasmicUsSearch.pageMetadata.canonical} />
      </Head>

      <style>{`
        body {
          margin: 0;
        }
      `}</style>

      <div className={projectcss.plasmic_page_wrapper}>
        <div
          data-plasmic-name={"root"}
          data-plasmic-override={overrides.root}
          data-plasmic-root={true}
          data-plasmic-for-node={forNode}
          className={classNames(
            projectcss.all,
            projectcss.root_reset,
            projectcss.plasmic_default_styles,
            projectcss.plasmic_mixins,
            styleTokensClassNames,
            styleTokensClassNames_antd_5_hostless,
            styleTokensClassNames_plasmic_rich_components,
            sty.root
          )}
        >
          {(() => {
            const child$Props = {
              className: classNames("__wab_instance", sty.us),
              eatdrinkShow: (() => {
                try {
                  return $queries.eatdrinkDataUs;
                } catch (e) {
                  if (
                    e instanceof TypeError ||
                    e?.plasmicType === "PlasmicUndefinedDataError"
                  ) {
                    return {};
                  }
                  throw e;
                }
              })(),
              footerNavigatorOnClickButtonNavBar: generateStateValueProp(
                $state,
                ["us", "footerNavigatorOnClickButtonNavBar"]
              ),
              footerNavigatorTextboxValue: generateStateValueProp($state, [
                "us",
                "footerNavigatorTextboxValue"
              ]),
              headerSearchBarValue: generateStateValueProp($state, [
                "us",
                "headerSearchBarValue"
              ]),
              headerSearchButtonNearMeDisable: generateStateValueProp($state, [
                "us",
                "headerSearchButtonNearMeDisable"
              ]),
              headerSearchButtonSearchDisable: generateStateValueProp($state, [
                "us",
                "headerSearchButtonSearchDisable"
              ]),
              headerSearchPlaceholder: "Search eat drink in USA",
              link: "/us/menu",
              onChangeSearchText: async event => {
                const $steps = {};

                $steps["goToUsSearch"] =
                  $state.us.headerSearchBarValue == null ||
                  $state.us.headerSearchBarValue.trim() === ""
                    ? (() => {
                        const actionArgs = { destination: `/us/search/${""}` };
                        return (({ destination }) => {
                          if (
                            typeof destination === "string" &&
                            destination.startsWith("#")
                          ) {
                            document
                              .getElementById(destination.substr(1))
                              .scrollIntoView({ behavior: "smooth" });
                          } else {
                            __nextRouter?.push(destination);
                          }
                        })?.apply(null, [actionArgs]);
                      })()
                    : undefined;
                if (
                  $steps["goToUsSearch"] != null &&
                  typeof $steps["goToUsSearch"] === "object" &&
                  typeof $steps["goToUsSearch"].then === "function"
                ) {
                  $steps["goToUsSearch"] = await $steps["goToUsSearch"];
                }
              },
              onClickButtonNavBar: hasVariant(
                globalVariants,
                "screen",
                "mobileOnly"
              )
                ? {}
                : undefined,
              onClickClearSearchText: async event => {
                const $steps = {};

                $steps["updateMyHeaderSearchBarValue"] = true
                  ? (() => {
                      const actionArgs = {
                        variable: {
                          objRoot: $state,
                          variablePath: ["us", "headerSearchBarValue"]
                        },
                        operation: 0,
                        value: ""
                      };
                      return (({
                        variable,
                        value,
                        startIndex,
                        deleteCount
                      }) => {
                        if (!variable) {
                          return;
                        }
                        const { objRoot, variablePath } = variable;

                        $stateSet(objRoot, variablePath, value);
                        return value;
                      })?.apply(null, [actionArgs]);
                    })()
                  : undefined;
                if (
                  $steps["updateMyHeaderSearchBarValue"] != null &&
                  typeof $steps["updateMyHeaderSearchBarValue"] === "object" &&
                  typeof $steps["updateMyHeaderSearchBarValue"].then ===
                    "function"
                ) {
                  $steps["updateMyHeaderSearchBarValue"] = await $steps[
                    "updateMyHeaderSearchBarValue"
                  ];
                }

                $steps["updateMyHeaderSearchBarValue2"] = true
                  ? (() => {
                      const actionArgs = { destination: `/us/search/${""}` };
                      return (({ destination }) => {
                        if (
                          typeof destination === "string" &&
                          destination.startsWith("#")
                        ) {
                          document
                            .getElementById(destination.substr(1))
                            .scrollIntoView({ behavior: "smooth" });
                        } else {
                          __nextRouter?.push(destination);
                        }
                      })?.apply(null, [actionArgs]);
                    })()
                  : undefined;
                if (
                  $steps["updateMyHeaderSearchBarValue2"] != null &&
                  typeof $steps["updateMyHeaderSearchBarValue2"] === "object" &&
                  typeof $steps["updateMyHeaderSearchBarValue2"].then ===
                    "function"
                ) {
                  $steps["updateMyHeaderSearchBarValue2"] = await $steps[
                    "updateMyHeaderSearchBarValue2"
                  ];
                }
              },
              onClickMobileNearMe: async event => {
                const $steps = {};

                $steps["updateMyFooterNavigatorOnClickButtonNavBar"] =
                  $state.us.footerNavigatorOnClickButtonNavBar.Location ===
                  false
                    ? (() => {
                        const actionArgs = {
                          variable: {
                            objRoot: $state,
                            variablePath: [
                              "us",
                              "footerNavigatorOnClickButtonNavBar"
                            ]
                          },
                          operation: 0,
                          value: {
                            Home: false,
                            Location: true,
                            Search: false
                          }
                        };
                        return (({
                          variable,
                          value,
                          startIndex,
                          deleteCount
                        }) => {
                          if (!variable) {
                            return;
                          }
                          const { objRoot, variablePath } = variable;

                          $stateSet(objRoot, variablePath, value);
                          return value;
                        })?.apply(null, [actionArgs]);
                      })()
                    : undefined;
                if (
                  $steps["updateMyFooterNavigatorOnClickButtonNavBar"] !=
                    null &&
                  typeof $steps[
                    "updateMyFooterNavigatorOnClickButtonNavBar"
                  ] === "object" &&
                  typeof $steps["updateMyFooterNavigatorOnClickButtonNavBar"]
                    .then === "function"
                ) {
                  $steps["updateMyFooterNavigatorOnClickButtonNavBar"] =
                    await $steps["updateMyFooterNavigatorOnClickButtonNavBar"];
                }
              },
              onClickMobileSearch: async event => {
                const $steps = {};

                $steps["goToUsSearch"] = true
                  ? (() => {
                      const actionArgs = {
                        destination: `/us/search/${(() => {
                          try {
                            return (() => {
                              function toSlug(input) {
                                return input
                                  .toString()
                                  .normalize("NFKD")
                                  .toLowerCase()
                                  .trim()
                                  .replace(
                                    /[^a-z0-9\u00C0-\u024F\u0600-\u06FF\u4E00-\u9FFF\s-]/g,
                                    ""
                                  )
                                  .replace(/[\s_-]+/g, "-")
                                  .replace(/^-+|-+$/g, "");
                              }
                              const slug = $state.us.footerNavigatorTextboxValue
                                ? toSlug($state.us.footerNavigatorTextboxValue)
                                : "";
                              return slug;
                            })();
                          } catch (e) {
                            if (
                              e instanceof TypeError ||
                              e?.plasmicType === "PlasmicUndefinedDataError"
                            ) {
                              return undefined;
                            }
                            throw e;
                          }
                        })()}`
                      };
                      return (({ destination }) => {
                        if (
                          typeof destination === "string" &&
                          destination.startsWith("#")
                        ) {
                          document
                            .getElementById(destination.substr(1))
                            .scrollIntoView({ behavior: "smooth" });
                        } else {
                          __nextRouter?.push(destination);
                        }
                      })?.apply(null, [actionArgs]);
                    })()
                  : undefined;
                if (
                  $steps["goToUsSearch"] != null &&
                  typeof $steps["goToUsSearch"] === "object" &&
                  typeof $steps["goToUsSearch"].then === "function"
                ) {
                  $steps["goToUsSearch"] = await $steps["goToUsSearch"];
                }
              },
              onClickNear: async event => {
                const $steps = {};

                $steps["invokeGlobalAction"] = true
                  ? (() => {
                      const actionArgs = { args: [] };
                      return $globalActions[
                        "UserCurrentLocation.requestPermission"
                      ]?.apply(null, [...actionArgs.args]);
                    })()
                  : undefined;
                if (
                  $steps["invokeGlobalAction"] != null &&
                  typeof $steps["invokeGlobalAction"] === "object" &&
                  typeof $steps["invokeGlobalAction"].then === "function"
                ) {
                  $steps["invokeGlobalAction"] = await $steps[
                    "invokeGlobalAction"
                  ];
                }
              },
              onClickSearch: async event => {
                const $steps = {};

                $steps["goToUsSearch"] = true
                  ? (() => {
                      const actionArgs = {
                        destination: `/us/search/${(() => {
                          try {
                            return (() => {
                              function toSlug(input) {
                                return input
                                  .toString()
                                  .normalize("NFKD")
                                  .toLowerCase()
                                  .trim()
                                  .replace(
                                    /[^a-z0-9\u00C0-\u024F\u0600-\u06FF\u4E00-\u9FFF\s-]/g,
                                    ""
                                  )
                                  .replace(/[\s_-]+/g, "-")
                                  .replace(/^-+|-+$/g, "");
                              }
                              const slug = $state.us.headerSearchBarValue
                                ? toSlug($state.us.headerSearchBarValue)
                                : "";
                              return slug;
                            })();
                          } catch (e) {
                            if (
                              e instanceof TypeError ||
                              e?.plasmicType === "PlasmicUndefinedDataError"
                            ) {
                              return undefined;
                            }
                            throw e;
                          }
                        })()}`
                      };
                      return (({ destination }) => {
                        if (
                          typeof destination === "string" &&
                          destination.startsWith("#")
                        ) {
                          document
                            .getElementById(destination.substr(1))
                            .scrollIntoView({ behavior: "smooth" });
                        } else {
                          __nextRouter?.push(destination);
                        }
                      })?.apply(null, [actionArgs]);
                    })()
                  : undefined;
                if (
                  $steps["goToUsSearch"] != null &&
                  typeof $steps["goToUsSearch"] === "object" &&
                  typeof $steps["goToUsSearch"].then === "function"
                ) {
                  $steps["goToUsSearch"] = await $steps["goToUsSearch"];
                }
              },
              onFooterNavigatorOnClickButtonNavBarChange: async (
                ...eventArgs: any
              ) => {
                generateStateOnChangeProp($state, [
                  "us",
                  "footerNavigatorOnClickButtonNavBar"
                ]).apply(null, eventArgs);

                if (
                  eventArgs.length > 1 &&
                  eventArgs[1] &&
                  eventArgs[1]._plasmic_state_init_
                ) {
                  return;
                }
              },
              onFooterNavigatorTextboxValueChange: async (
                ...eventArgs: any
              ) => {
                generateStateOnChangeProp($state, [
                  "us",
                  "footerNavigatorTextboxValue"
                ]).apply(null, eventArgs);

                if (
                  eventArgs.length > 1 &&
                  eventArgs[1] &&
                  eventArgs[1]._plasmic_state_init_
                ) {
                  return;
                }
              },
              onHeaderSearchBarValueChange: async (...eventArgs: any) => {
                generateStateOnChangeProp($state, [
                  "us",
                  "headerSearchBarValue"
                ]).apply(null, eventArgs);

                if (
                  eventArgs.length > 1 &&
                  eventArgs[1] &&
                  eventArgs[1]._plasmic_state_init_
                ) {
                  return;
                }
              },
              onHeaderSearchButtonNearMeDisableChange: async (
                ...eventArgs: any
              ) => {
                generateStateOnChangeProp($state, [
                  "us",
                  "headerSearchButtonNearMeDisable"
                ]).apply(null, eventArgs);

                if (
                  eventArgs.length > 1 &&
                  eventArgs[1] &&
                  eventArgs[1]._plasmic_state_init_
                ) {
                  return;
                }
              },
              onHeaderSearchButtonSearchDisableChange: async (
                ...eventArgs: any
              ) => {
                generateStateOnChangeProp($state, [
                  "us",
                  "headerSearchButtonSearchDisable"
                ]).apply(null, eventArgs);

                if (
                  eventArgs.length > 1 &&
                  eventArgs[1] &&
                  eventArgs[1]._plasmic_state_init_
                ) {
                  return;
                }
              }
            };

            initializePlasmicStates(
              $state,
              [
                {
                  name: "us.headerSearchBarValue",
                  initFunc: ({ $props, $state, $queries }) =>
                    (() => {
                      try {
                        return (() => {
                          function fromSlug(slug) {
                            return (slug ?? "")
                              .toString()
                              .replace(/-/g, " ")
                              .replace(/\s+/g, " ")
                              .trim();
                          }
                          return fromSlug($ctx?.params?.search_text);
                        })();
                      } catch (e) {
                        if (
                          e instanceof TypeError ||
                          e?.plasmicType === "PlasmicUndefinedDataError"
                        ) {
                          return undefined;
                        }
                        throw e;
                      }
                    })()
                }
              ],
              []
            );
            return (
              <TemplateCountry
                data-plasmic-name={"us"}
                data-plasmic-override={overrides.us}
                {...child$Props}
              />
            );
          })()}
        </div>
      </div>
    </React.Fragment>
  ) as React.ReactElement | null;
}

const PlasmicDescendants = {
  root: ["root", "us"],
  us: ["us"]
} as const;
type NodeNameType = keyof typeof PlasmicDescendants;
type DescendantsType<T extends NodeNameType> =
  (typeof PlasmicDescendants)[T][number];
type NodeDefaultElementType = {
  root: "div";
  us: typeof TemplateCountry;
};

type ReservedPropsType = "variants" | "args" | "overrides";
type NodeOverridesType<T extends NodeNameType> = Pick<
  PlasmicUsSearch__OverridesType,
  DescendantsType<T>
>;
type NodeComponentProps<T extends NodeNameType> =
  // Explicitly specify variants, args, and overrides as objects
  {
    variants?: PlasmicUsSearch__VariantsArgs;
    args?: PlasmicUsSearch__ArgsType;
    overrides?: NodeOverridesType<T>;
  } & Omit<PlasmicUsSearch__VariantsArgs, ReservedPropsType> & // Specify variants directly as props
    // Specify args directly as props
    Omit<PlasmicUsSearch__ArgsType, ReservedPropsType> &
    // Specify overrides for each element directly as props
    Omit<
      NodeOverridesType<T>,
      ReservedPropsType | VariantPropType | ArgPropType
    > &
    // Specify props for the root element
    Omit<
      Partial<React.ComponentProps<NodeDefaultElementType[T]>>,
      ReservedPropsType | VariantPropType | ArgPropType | DescendantsType<T>
    >;

function makeNodeComponent<NodeName extends NodeNameType>(nodeName: NodeName) {
  type PropsType = NodeComponentProps<NodeName> & { key?: React.Key };
  const func = function <T extends PropsType>(
    props: T & StrictProps<T, PropsType>
  ) {
    const { variants, args, overrides } = React.useMemo(
      () =>
        deriveRenderOpts(props, {
          name: nodeName,
          descendantNames: PlasmicDescendants[nodeName],
          internalArgPropNames: PlasmicUsSearch__ArgProps,
          internalVariantPropNames: PlasmicUsSearch__VariantProps
        }),
      [props, nodeName]
    );
    return PlasmicUsSearch__RenderFunc({
      variants,
      args,
      overrides,
      forNode: nodeName
    });
  };
  if (nodeName === "root") {
    func.displayName = "PlasmicUsSearch";
  } else {
    func.displayName = `PlasmicUsSearch.${nodeName}`;
  }
  return func;
}

export const PlasmicUsSearch = Object.assign(
  // Top-level PlasmicUsSearch renders the root element
  makeNodeComponent("root"),
  {
    // Helper components rendering sub-elements
    us: makeNodeComponent("us"),

    // Metadata about props expected for PlasmicUsSearch
    internalVariantProps: PlasmicUsSearch__VariantProps,
    internalArgProps: PlasmicUsSearch__ArgProps,

    // Page metadata
    pageMetadata: {
      title: "Search eatdrink in USA",
      description:
        "This is the focal point of food and drink in USA. Search eat drink to discover food and drink near you.",
      ogImageSrc:
        "https://site-assets.plasmic.app/00afc728514153670288d6386193de5c.svg",
      canonical: "https://eatdr.ink/us/search"
    }
  }
);

export default PlasmicUsSearch;
/* prettier-ignore-end */

Answers to your questions:-

  1. I am not using or touching the globalContext nor having any _useGlobalVariants. I actually changed the page component to use SSR as in pages\us\search[[…search_text]].tsx which I shared earlier.

  2. I am using Pages router

  3. After making the changes the error is resolved. But I was hesistant to edit the PlasmicUsSearch as this file is auto-generated by Plasmic and I might overlook in the future while maintaining the code.

@mouthains I will investigate why it generates the code this way and let you know as soon as I find the root cause.

Thank you for your kind attention.

Just to share ChatGPT comments on the PlasmicUsSearch code:

Here’s the key problem:

  • The closure for initFunc is created before const globalVariants = … runs.
  • During SSR prepass (extractPlasmicQueryData), React eagerly evaluates those initFuncs → tries to access globalVariants before it exists → boom.

This is actually a known bug in some versions of @plasmicapp/react-web (ordering of useGlobalVariants). Upgrading Plasmic dependencies often fixes it.

@mouthains can you also send your project ID so that we can reproduce it easily from our end?

The project ID concerned is rSNJxoyWcY3xfv1fFT5emw.

Thank you.

@mouthains, we just pushed a fix for the codegen, which should address your issue.
Can you try to sync and see if there are any errors from your end?

Thank you so much the error has been resolved.

1 Like