Can't render pages created in editor from our codebase

What are you trying to do? (please be as specific as possible and include relevant screenshots, code snippets, and reproduction steps)

Tl;Dr We are attempting to view the pages that we have created in the Plasmic editor from our code base.

We have created pages in the Plasmic editor which contain some of our custom code components. We have added the importPath prop to all of these components and everything seems to be working fine in the editor. We can view and edit the components as we see fit. We can then create and publish a page, and successfully run the plasmic sync command.

The plasmic sync works as intended and we can see our updates in the /src/components/plasmic folder. We can see them but we’re not editing them.

The issue then arises when we attempt to add one of these pages to a route and navigate to it.

We receive this error for every custom code component used on the page:

The issue clearly mentions the import path being the cause. Which makes sense, because the import path is indeed outside of the src/ directory. The issue, however, is that these are coming from the plasmic generated pages. The ones that we don’t touch because they will be changed.

I will go into more detail about what I’ve done to fix it below. But first…

Some extra information

We bootstrapped with create-plasmic-app. Following this documentation.

Our project tree

/node_modules
/public
/src
  /components
    /Button
      Button.tsx
      Button.scss
    /plasmic // Plasmic generated files are here
    plasmic-tokens.theo.json
    // Plasmic skeleton components will add here
  App.jsx
  index.css
  index.js
package.json
package-lock.json
plasmic.json
plasmic.lock

Our plasmic.json (just what is relevant)

{
"platform": "react",
  "code": {
    "lang": "js",
    "scheme": "blackbox",
    "reactRuntime": "classic"
  },
  "style": {
    "scheme": "css-modules",
    "defaultStyleCssFilePath": "plasmic/plasmic__default_style.module.css"
  },
  "images": {
    "scheme": "files",
    "publicDir": "../../public",
    "publicUrlPrefix": "/static/"
  },
  "tokens": {
    "scheme": "theo",
    "tokensFilePath": "plasmic-tokens.theo.json"
  },
  "srcDir": "src/components",
  "defaultPlasmicDir": "./plasmic"
}

Our App.jsx file

import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import renderPlasmicComponents from './hooks/renderPlasmicComponents.jsx';

import ErrorPage from './components/ErrorPage.jsx';


function App() {
  return (
    <Router>
      <Routes>
        <Route path="/error" element={<ErrorPage />} />

        <Route path="/plasmic-host" element={ renderPlasmicComponents() } />
      </Routes>
    </Router>
  );
}

export default App;
  

The generated skeleton component attempting to be rendered

// This is a skeleton starter React component generated by Plasmic.
// This file is owned by you, feel free to edit as you see fit.
import * as React from "react";
import { PlasmicErrorPage } from "./plasmic/pure_athlete/PlasmicErrorPage";

function ErrorPage_(props, ref) {
  // Use PlasmicErrorPage to render this component as it was
  // designed in Plasmic, by activating the appropriate variants,
  // attaching the appropriate event handlers, etc.  You
  // can also install whatever React hooks you need here to manage state or
  // fetch data.
  //
  // Props you can pass into PlasmicErrorPage are:
  // 1. Variants you want to activate,
  // 2. Contents for slots you want to fill,
  // 3. Overrides for any named node in the component to attach behavior and data,
  // 4. Props to set on the root node.
  //
  // By default, we are just piping all ErrorPageProps here, but feel free
  // to do whatever works for you.
  return <PlasmicErrorPage root={{ ref }} {...props} />;
}

const ErrorPage = React.forwardRef(ErrorPage_);

export default ErrorPage;

The Plasmic generated page imports

import * as React from "react";
import {
  PlasmicImg as PlasmicImg__,
  PlasmicLink as PlasmicLink__,
  classNames,
  createPlasmicElementProxy,
  deriveRenderOpts,
  ensureGlobalVariants
} from "@plasmicapp/react-web";
import { useDataEnv } from "@plasmicapp/react-web/lib/host";
import { Layout } from "../../../../components/Layout/Layout"; // plasmic-import: qbi5tp3JEcNe/codeComponent
import Hero from "../../Hero"; // plasmic-import: KTTPrT7mzY4J/component
import { MobileSubNavigation } from "../../../../components/Navigation/MobileSubNavigation"; // plasmic-import: QgZ2_UyxFn0M/codeComponent
import { LinkDropDown } from "../../../../components/DropDown/LinkDropDown"; // plasmic-import: GF5qVkZ7fKvI/codeComponent
import { Button } from "../../../../components/Button/Button"; // plasmic-import: 55c-Kvovdhvg/codeComponent
import { useScreenVariants as useScreenVariants_1SgyRxnF80Kn } from "./PlasmicGlobalVariant__Screen"; // plasmic-import: 1SgyRxnF80kn/globalVariant
import "@plasmicapp/react-web/lib/plasmic.css";
import projectcss from "./plasmic.module.css"; // plasmic-import: sWBc8TNgqxWGyF1q7TmzV7/projectcss
import sty from "./PlasmicErrorPage.module.css"; // plasmic-import: P54roMW-SNyh/css
import image1PngRuFirDr5LbOc from "./images/image1Png.png"; // plasmic-import: ruFirDR5LbOc/picture

An example of a component

import React, { ReactNode } from "react";
import { Navigation, NavigationPlasmicProps } from "../Navigation/Navigation.tsx";
import { Footer, FooterPlasmicProps } from "../Footer/Footer.tsx";
import "./Layout.scss";

export interface LayoutProps {
    children: ReactNode;
    navigationChildren: ReactNode;
    navigationMobileChildren: ReactNode;
    footerChildren: ReactNode;
};

export const LayoutPlasmicProps = {
    name: 'Layout',
    importPath: './Layout/Layout.tsx',
    props: {
        children: {
            type: 'slot',
            defaultValue: [{ type: 'box' }]
        },
        footerChildren: { ...FooterPlasmicProps.props.children },
        navigationChildren: { ...NavigationPlasmicProps.props.children },
        navigationMobileChildren: { ...NavigationPlasmicProps.props.mobileChildren }
    }
};

function Layout({
    children,
    navigationChildren,
    navigationMobileChildren,
    footerChildren
}: LayoutProps) {
    return (
        <div className="page-wrapper flex">
            <Navigation
                children={navigationChildren}
                mobileChildren={navigationMobileChildren}
            />
            
            <main>{children}</main>
            
            <Footer
                children={footerChildren}
            />
        </div>
    )
};

export { Layout };

What have you tried so far? (please link relevant docs and other forum posts)

Initially, we attempted to update our importPath for our custom components. According to this documentation, the importPath prop:

It can be the name of the npm package that contains the component (antd), or the path to the file in the project (relative to the root directory, where the plasmic.json file is located)

Based upon that, our initial importPath was ./src/components/ComponentFile/Component.tsx. However, this still gave us the same issue. As you can see from the example component above, we’ve updated this serveral times. Though it doesn’t seem to make much of a difference. As it will always try pulling from outside the src/ directory.

We’ve tried updating the srcDir in the plasmic.json file several times. Still with the same result.

We also tried moving the plasmic.json file into the src/ directory. This didn’t help as we then received an error about attempting to use paths outside the srcDir path. Specifically, when setting the images/publicDir path. As the public/ directory is indeed outside of the src/ directory…

We then took another look at the documentation around the plasmic.json file. But haven’t been able to find anything of use. As far as I can tell, we have everything set up appropriately. We are specifiying an importPath that is relative to the plasmic.json file, which is in our root directory. All of this was set up with the create-plasmic-app package. So what are we missing here?

The only thing that we have found works is to go into these generated files and manually update the import paths for our custom components. But that is not a viable solution.

Relevant links:

We have solved our issue.

One of our developers noticed that we had setup our project to utilize JavaScript, instead of TypeScript, on the initial creation with create-plasmic-app.

Because of this, we just needed to migrate our react app from JavaScript to TypeScript. We followed this stack overflow post for directions on doing this for a create-react-app bootstrapped project without having to eject anything.

This allowed our pages to actually render from the codebase. Although, the new issue was Conflicting peer dependency for typescript. Which was an upstream conflict introduced because the create-plasmic-app typescript template uses a version of TS that conflicts with the @types/ package.

At first we tried to do as the almighy Stack Overflow commanded and replace react-scripts with react-scripts-ts. But that didn’t work. Instead, we installed the previous version of TypeScript npm install typescript@^4.9.5. Which is the version the create-plasmic-app template uses. With that install, we were able to install the @types/ package and get everything up and running!