Plasmic targeting setup issues

Hi, at the moment I am experiencing problems with setting up targeting in Plasmic. I followed the steps from the documentation:

  1. Register traits in plasmic-init.ts
  2. Extract the traits in the next.js middleware.ts and pass them to getMiddlewareResponse to get the correct rewrite (this works, debugged this)
  3. In the catchall route:
    a. I extracted the variation using rewriteWithoutTraits and passing the traits variable to getActiveVariation. (inside getStaticProps)
    b. Pass the variation variable to the PlasmicRootProvider so that it can request the correct page content
  4. Inside Plasmic Studio:
    a. Create a new “targeted content” Segment using one of the traits I created in code (they also show up correctly in Plasmic) and turn it to “on”
    b. Make changes to a page for this segment
    c. Load the page with the defined targetings (e.g. url parameter)
    Somehow I always get the base version of the page even if I am passing the correct targetings (and the rewrite happens correctly inside the middleware)

Hi Daniel, could you share your catch all code ?

Sure, I hope this works for you:

import {
  ComponentRenderData,
  PageMeta,
  PlasmicComponent,
  PlasmicRootProvider,
  extractPlasmicQueryData,
} from "@plasmicapp/loader-nextjs";
import {
  generateAllPaths,
  getActiveVariation,
  rewriteWithoutTraits,
} from "@plasmicapp/loader-nextjs/edge";
import { GetStaticPaths, GetStaticProps } from "next";
import Error from "next/error";
import { useRouter } from "next/router";

import domains, {
  DomainConfig,
  getConfigForDomainName,
} from "@/config/domains";
import IGNORED_PATHS from "@/config/ignoredPaths";
import REVALIDATE from "@/config/revalidate";
import usePageViewEvent from "@/hooks/usePageViewEvent";
import PLASMIC from "plasmic-init";

interface CatchallPageProps {
  plasmicData?: ComponentRenderData;
  queryCache?: Record<string, any>;
  variation?: Record<string, string>;
  projectId: string;
}

const NOT_FOUND = {
  props: {} as CatchallPageProps,
  notFound: true,
  revalidate: REVALIDATE,
};

const filterPage = (page: PageMeta, config: DomainConfig) =>
  page.projectId === config.plasmic.id && !IGNORED_PATHS.includes(page.path);

const mapPageToStaticPathObjects = (page: PageMeta, domainName: string) =>
  // This generates all possible variant paths for a given page, e.g. for a/b tests
  // @ts-expect-error - There is a bug in the types for `@plasmicapp/loader-nextjs/edge`
  generateAllPaths(page.path).map((path: string) => ({
    params: { catchall: path.slice(1).split("/"), domainName },
  }));

/**
 * Use fetchPages() to fetch list of pages that have been created in Plasmic
 */
export const getStaticPaths: GetStaticPaths = async () => {
  const pages = await PLASMIC.fetchPages();

  return {
    paths: Object.entries(domains).flatMap(([domainName, config]) =>
      pages
        .filter((page) => filterPage(page, config))
        .flatMap((page) => mapPageToStaticPathObjects(page, domainName)),
    ),
    fallback: "blocking",
  };
};

/**
 * For each page, pre-fetch the data we need to render it
 */
export const getStaticProps: GetStaticProps<CatchallPageProps> = async (
  context,
) => {
  const { catchall, domainName } = context.params ?? {};
  const domainConfig = getConfigForDomainName(domainName as string);

  if (!domainConfig) {
    return NOT_FOUND;
  }

  // Convert the catchall param into a path string
  const rawPlasmicPath =
    typeof catchall === "string"
      ? catchall
      : Array.isArray(catchall)
      ? `/${catchall.join("/")}`
      : "/";

  // Parse the path, and extract the traits.
  // @ts-expect-error - There is a bug in the types for `@plasmicapp/loader-nextjs/edge`
  const { path: plasmicPath, traits } = rewriteWithoutTraits(rawPlasmicPath);

  // Ignore paths that we don't want to render (e.g. error pages created inside Plasmic)
  if (IGNORED_PATHS.includes(plasmicPath)) {
    return NOT_FOUND;
  }

  const plasmicData = await PLASMIC.maybeFetchComponentData({
    name: plasmicPath,
    projectId: domainConfig.settings.plasmic.id,
  });
  if (!plasmicData) {
    // No data found in Plasmic for this path
    return NOT_FOUND;
  }

  // Choose the variation of the page to use from Plasmic based on the traits
  // @ts-expect-error - There is a bug in the types for `@plasmicapp/loader-nextjs/edge`
  const variation = getActiveVariation({
    splits: PLASMIC.getActiveSplits(),
    traits,
    path: plasmicPath,
  });

  const pageMeta = plasmicData.entryCompMetas[0];

  // Cache the necessary data fetched for the page.
  const queryCache = await extractPlasmicQueryData(
    <PlasmicRootProvider
      loader={PLASMIC}
      prefetchedData={plasmicData}
      pageParams={pageMeta.params}
      variation={variation}
      skipFonts
    >
      <PlasmicComponent
        component={pageMeta.displayName}
        projectId={domainConfig.settings.plasmic.id}
      />
    </PlasmicRootProvider>,
  );

  // Pass the data in as props.
  return {
    props: {
      plasmicData,
      queryCache,
      variation,
      projectId: domainConfig.settings.plasmic.id,
    },
    // Using incremental static regeneration, will invalidate this page
    // after 60s (no deploy webhooks needed)
    revalidate: REVALIDATE,
  };
};

const CatchallPage = (props: CatchallPageProps) => {
  const { plasmicData, queryCache, variation, projectId } = props;
  const router = useRouter();

  usePageViewEvent();

  if (!plasmicData || plasmicData.entryCompMetas.length === 0) {
    return <Error statusCode={404} />;
  }
  const pageMeta = plasmicData.entryCompMetas[0];

  return (
    // Pass in the data fetched in getStaticProps as prefetchedData
    <PlasmicRootProvider
      loader={PLASMIC}
      prefetchedData={plasmicData}
      prefetchedQueryData={queryCache}
      variation={variation}
      pageParams={pageMeta.params}
      pageQuery={router.query}
      skipFonts
    >
      <PlasmicComponent
        component={pageMeta.displayName}
        projectId={projectId}
      />
    </PlasmicRootProvider>
  );
};

export default CatchallPage;

Yeah, your catch-all looks good, could you pass me your project-id and which traits you registered ? I will also look in the type error that you mentioned in the code

@fmota This is the project where I am trying this out atm. Note that is uses localhost as a host: https://studio.plasmic.app/projects/ooVuhYCm7CroBfiXV411Te/-/Hello-Weasels

Hi @exquisite_spider, just FYI @fmota is actively looking into this right now, and will report back

Hi @exquisite_spider, I am still not able to reproduce the issue, one thing that I realized was that in the last published version is expecting the channel to be equal to sea_brand but in the un published state is expecting channel to be equal to dis_gdn, you mentioned that you debugged your middleware.ts but could you share it ?

@fmota I sent you the code in a private chat.