Navigating to pages from plasmic pages does not work. react-router-dom v6

What are you trying to do? (please be as specific as possible and include relevant screenshots, code snippets)
I am trying to use plasmic for authored pages. I am trying to link other pages from links and buttons in plasmic pages.

What are the reproduction steps?
start a vanilla reactjs project with plasmic catchall pages
Create a home page plasmic page with a call to action button
add an interaction, go to page on onclick to go to another plasmic page

Relevant links:

Can someone guide me on how to do this properly so that this will work. This works locally but when I deploy, it doesnt work. Where when I link pages using component of react router dom v6, it works

It looks like your server isn’t responding to a URL like https://wf-react-storefront.onrender.com/holidays/wayanad

My guess is that you haven’t configured your server to handle URLs other than the index page properly. How is your React app hosted?

The same URL works when it is accessed through a react-router-dom Link component(try stays from top navigation). When it is accessed by directly typing the URL in address bar and when it is accessed through Links in plasmic pages, it says not found.

App is hosted in render as a static site. I was expecting Plasmic catch all pages to handle this. Pasting app.js where plasmic is set up as per documentation for your reference.

import './App.css';
import {
  PlasmicRootProvider,
  ComponentRenderData,
  PlasmicComponent,
} from '@plasmicapp/loader-react';
import { useQuery } from '@apollo/client';
import { PLASMIC } from './compoents/plasmic/plasmic-init';
import { useLocation } from 'react-router-dom';
import { useEffect, useState, useContext } from 'react';
import { CartContext } from './contexts/CartContext';
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import Register from './compoents/accounts/Register';
import Login from './compoents/accounts/Login';
import ErrorMessage from './compoents/layouts/ErrorMessage';
import Profile from './compoents/accounts/Profile';
import Header from './compoents/layouts/Header';
import PrivateRoutes from './utils/PrivateRoutes';
import Footer from './compoents/plasmic/Footer';
import Collections from './compoents/pages/Collections';
import ProductList from './compoents/pages/ProductList';
import ProductPage from './compoents/pages/ProductPage';
import CartPage from './compoents/pages/CartPage';
import CheckoutPage from './compoents/pages/CheckoutPage';
import { GET_ACTIVE_ORDER } from './utils/queries';

function App() {
  //if there is an active order(cart) in the back end, update that in the cart context
  const { dispatch } = useContext(CartContext);
  const { data: cartData, loading: cartLoading, error: cartError } = useQuery(GET_ACTIVE_ORDER);
  useEffect(() => {
    if (!cartLoading && !cartError) {
      const fetchedData = cartData?.activeOrder;
      if (fetchedData) {
        dispatch({
          type: "UPDATE_CART",
          payload: fetchedData
        });
      }
    }
  }, [cartData, cartLoading, cartError, dispatch]); // Ensure this effect runs only once when the component mounts.

  return (
      <PlasmicRootProvider loader={PLASMIC}>
        <Router>
          <Header></Header>
          <ErrorMessage></ErrorMessage>
          <Routes>
            {/* <Route exact path="/" element={<HomePage/>} /> */}
            {/* Add the catch-all route for other paths */}
            <Route path="*" element={<CatchAllPage />} />
            <Route exact path="/register" element={<Register />} />
            <Route exact path="/login" element={<Login />} />
            <Route exact path ="/products" element={<Collections/>} />
            <Route path="/products/:slug" element={<ProductList/>} />
            <Route path="/products/detail/:slug" element={<ProductPage/>} />
            <Route path="/cart" element={<CartPage/>} />
            <Route exact path="/checkout" element={<CheckoutPage/>} /> 
            <Route exact path="/profile" element={
              <PrivateRoutes>
                <Profile />
              </PrivateRoutes>
            } />
            
          </Routes>
          <Footer></Footer>
        </Router>
      </PlasmicRootProvider>
  );
}

export default App;
//plasmic pages
function CatchAllPage() {
  const [loading, setLoading] = useState(true);
  const [pageData, setPageData] = useState(null); // Use a simpler type here

  const location = useLocation(); // Access current location

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

  if (loading) {
    return <div>Loading...</div>;
  }
  if (!pageData) {
    return <div>Not found</div>;
  }

  return <PlasmicComponent component={location.pathname} />;
}

FYI I edited your post to put your code in backticks so it shows up in a code block. You can do that yourself next time by surrounding code like this:

```
your code goes here
```

Yes the Plasmic catchall page should work. But I think the problem is how your hosting works (i.e. how do you deploy to Render). Your app in Render is not responding to non-index URLs. Did you try following the directions for using client-side routing?

You can also test if Plasmic is the issue here. Try adding a new route like

<Route path="/something" element={<div>Can you see this?</div>} />

And see if you can visit that URL directly.

1 Like

Hey Jason, I tried the instructions to configure redirections for using client-side routing in render. It works! Big Thanks.
Now plasmic is able to show the appropriate pages but the app reloads when I click on links. to better handle the situation by using the component of the react-router-dom, what would you recommend? I am coming from another world of DXP and awestruck by the capability of plasmic.

Can you please try passing in the Link component from React Router into wherever you put your PlasmicRootProvider?

It will look something like this:

import { Link } from "react-router";

export function MyApp() {
  // ...
  return <PlasmicRootProvider
    // ...
    Link={Link}
  >
    // ...
  </PlasmicRootProvider>
}