Plasmic Studio shows Error: You must use <PlasmicRootProvider /> at the root of your app

I’m trying to create a CodeComponent that has several components that exists in plasmic studio.

import { PlasmicComponent } from '@plasmicapp/loader-nextjs';

export const FileListCodeComponent = ({ isPublic }: { isPublic: boolean }) => {
  return (
    <>
      <PlasmicComponent component="v3/file-list-header" forceOriginal />
      <PlasmicComponent component="v3/file-list-footer" forceOriginal />
    </>
  );
};

when running the app the component shows up properly, however on Plasmic studio I get the following error:

image

I do have the RootProvider set on my [[...catchall]].tsx as follow:

import { PLASMIC } from '@/plasmic-init';
import {
  ComponentRenderData,
  PlasmicComponent,
  PlasmicRootProvider,
  extractPlasmicQueryData,
} from '@plasmicapp/loader-nextjs';
import type { GetServerSideProps } from 'next';
import NextError from 'next/error';
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
import { ToastContainer } from 'react-toastify';

export default function PlasmicLoaderPage(props: {
  plasmicData?: ComponentRenderData;
  queryCache?: Record<string, unknown>;
}) {
  const { plasmicData, queryCache } = props;
  const router = useRouter();
  const [isClient, setIsClient] = useState(false);

  // This is necessary to prevent a flash of unstyled content on page load
  useEffect(() => {
    setIsClient(true);
  }, []);

  if (!isClient) {
    return null;
  }

  if (!plasmicData || plasmicData.entryCompMetas.length === 0) {
    return <NextError statusCode={404} />;
  }
  const pageMeta = plasmicData.entryCompMetas[0];
  return (
    <PlasmicRootProvider
      loader={PLASMIC}
      prefetchedData={plasmicData}
      prefetchedQueryData={queryCache}
      pageParams={pageMeta.params}
      pageQuery={router.query}
    >
      <PlasmicComponent component={pageMeta.displayName} />
      <ToastContainer style={{ marginTop: '80px' }} />
    </PlasmicRootProvider>
  );
}

export const getServerSideProps: GetServerSideProps = async (context) => {
  const { req, res } = context;
  const { catchall } = context.params ?? {};
  const plasmicPath =
    typeof catchall === 'string'
      ? catchall
      : Array.isArray(catchall)
      ? `/${catchall.join('/')}`
      : '/';

  const plasmicData = await PLASMIC.maybeFetchComponentData(plasmicPath);

  if (!plasmicData) {
    // non-Plasmic catch-all
    return { props: {} };
  }

  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}
    >
      <PlasmicComponent component={pageMeta.displayName} />
    </PlasmicRootProvider>
  );

  return {
    props: {
      plasmicData,
      queryCache,
    },
  };
};

The issue is, we need a designer from the team to be able to see the component in studio and make changes if needed, which is impossible right now since all he sees is a red error message.

Also The reason I’m creating the component is to add logic, etc, hence why I’m doing using code.

I don’t know if it is exactly an issue, but I wasn’t able to find and reference or help regarding this topic, please let me know if I’m doing something wrong

What are the reproduction steps?

Relevant links:

Hi @rafael_ferreira

Thanks for providing the details, can you please share the plasmic-host file?

You would need to wrap <PlasmicCanvasHost /> in PlasmicRootProvider in your plasmic host file in this case. The [[...catchall]] page works as a fallback for the routes that are not defined where as plasmic-host page is defined.

Interesting, did not know that. Here it is

import * as React from 'react';
import { PlasmicCanvasHost } from '@plasmicapp/loader-nextjs';
import { PLASMIC } from '../plasmic-init';

export default function PlasmicHost() {
  return PLASMIC && <PlasmicCanvasHost />;
}

So it becomes

import {
  PlasmicCanvasHost,
  PlasmicRootProvider,
} from '@plasmicapp/loader-nextjs';
import { PLASMIC } from '../plasmic-init';

export default function PlasmicHost() {
  return (
    PLASMIC && (
      <PlasmicRootProvider loader={PLASMIC}>
        <PlasmicCanvasHost />
      </PlasmicRootProvider>
    )
  );
}

Thank you so much for your help

1 Like