Nested routes in Remix flat routing showing 404 errors in Shopify application

I’m working on a Shopify app with Remix and using the flat routing system without external routing libraries. My folder setup looks like this:

store-builder
└── app
    └── routes
        └── app.products
            ├── $productId.jsx
            ├── index.jsx
            └── create.jsx

The main issue is that only the index.jsx file works properly when I run the Shopify development server. If I navigate to /app/products/create or /app/products/456, I get 404 errors even though these files exist and follow Remix flat route naming rules.

What works: Other routes like /app and /auth.signin function correctly.

What doesn’t work: Any child routes inside the app.products folder.

It looks like Remix isn’t recognizing the nested flat routes in the Shopify environment. Here’s my main app.jsx layout:

export default function AppLayout() {
  const { apiKey } = useLoaderData();

  return (
    <AppProvider isEmbeddedApp apiKey={apiKey}>
      <Navigation>
        <Link to="/app" rel="home">
          Dashboard
        </Link>
        <Link to="/app/products">Products</Link>
        <Link to="/app/settings">Settings</Link>
      </Navigation>
      <Outlet />
    </AppProvider>
  );
}

export function ErrorBoundary() {
  return boundary.error(useRouteError());
}

export const headers = (headersArgs) => {
  return boundary.headers(headersArgs);
};

Any ideas why Remix flat routing might not work for nested routes in Shopify apps?

I encountered a similar problem when setting up flat routing for a Shopify app. It seems the folder structure you’ve implemented may not align with Remix’s flat routing expectations. To resolve this, you’ll need to create a layout file named app.products.jsx in the routes directory. Then, rename your existing route files to follow this scheme: app.products.$productId.jsx, app.products.index.jsx, and app.products.create.jsx, and place them directly in the routes folder without any subdirectories. Remember, flat routing utilizes dot notation for nesting instead of physical folder hierarchies. This adjustment should help eliminate the 404 errors you’re facing. Additionally, ensure your new layout file includes an <Outlet /> for rendering child routes correctly.

Just dealt with this - super frustrating! You’re mixing folder structure with flat routing, which doesn’t work. Pick one: either use flat routing with files like app.products.create.jsx in the routes folder, or stick with regular folders. Shopify CLI hates when you mix both approaches.

This happens because Remix gets confused between your folder structure and file naming. You made a physical folder called app.products, but Remix’s flat routing wants file names with dots - not actual directories. Just move all your route files straight into the routes folder and rename them: app.products.jsx for the layout, app.products.index.jsx, app.products.create.jsx, and app.products.$productId.jsx. Delete that app.products folder completely. Had this exact same issue last month and spent hours debugging before I figured out Remix was reading the folder as a literal route segment instead of a namespace. Shopify’s dev server is really picky about routing conventions, so you need that flat file structure or it won’t work.