Custom code components/fetcher not working with useLocation() or useSearchParams()

So with this example, useLocation() or related functions would fail due to them not being wrapped inside , which is confusing since everything is wrapped in it by default following the react’s tutorial.

How do I make this work?

Hello @future_design,

I am not sure I understand your question.

Can you provide an example code component and what would be the expected behavior?

Hi,

I’ll try taking an example from the docs

App.tsx

function AppRoot() {
  return (
    <PlasmicRootProvider loader={PLASMIC}>
      <Router>
        <Routes>
          <Route path="/" element={CatchAllPage()} />
        </Routes>
      </Router>
    </PlasmicRootProvider>
  );
}

// We try loading the Plasmic page for the current route.
// If it doesn't exist, then return "Not found."
export function CatchAllPage() {
  const [loading, setLoading] = useState(true);
  const [pageData, setPageData] = useState<ComponentRenderData | null>(null);

  useEffect(() => {
    async function load() {
      const pageData = await PLASMIC.maybeFetchComponentData(location.pathname);
      setPageData(pageData);
      setLoading(false);
    }
    load();
  }, []);

  if (loading) {
    return <div>Loading...</div>;
  }
  if (!pageData) {
    return <div>Not found</div>;
  }
  // The page will already be cached from the `load` call above.
  return <PlasmicComponent component={location.pathname} />;
}


HelloWorld.tsx (fail useLocation here)

import * as React from 'react';

export interface HelloWorldProps {
  children?: React.ReactNode;
  className?: string;
  verbose?: boolean;
}

export function HelloWorld({ children, className, verbose }: HelloWorldProps) {
     **const location = useLocation(); // this would fail**

return (
    <div className={className} style={{ padding: '20px' }}>
      <p>Hello there! {verbose && 'Really nice to meet you!'}</p>
      <div>{children}</div>
    </div>
  );
}

and then registerComponent

PLASMIC.registerComponent(HelloWorld, {
  name: 'HelloWorld',
  props: {
    verbose: 'boolean',
    children: 'slot'
  }
});

That useLocation() I put inside HelloWorld there would not work, claiming it was not wrapped inside a Router component.

Hey @future_design,

Would you mind sharing your repo with us? You can DM here.

Sorry I can’t do that. But it’s basically everything in this example:

The only different is that my HelloWorld.tsx has a useLocation(). That’s it

I’ve tried it here with a simple setup and no error is thrown.

Whoever, in canvas/preview you will see a different result than in production. Because the canvas runs inside your hosted page. See print screen as example:
Canvas:


Local dev: