-1

I have a heading in Layout and I want to pass props to it. So I can start my <main> element.

Here is my Layout.tsx

<>
  <h1>{title}</h1>
  <main>
    <Outlet /> {/* children */}
  </main>
  <Footer />
</>

Here is my routes.ts

export default [
  layout('./layouts/Layout.tsx', [
    index('./pages/index.tsx'),
    route('product', './pages/product.tsx'),
    route('contact', './pages/contact.tsx'),
  ]),
] satisfies RouteConfig;

So I can have my page with pre-headding. E.g. about.tsx

<>
  <h2>Who are we</h2>
<>
0

1 Answer 1

1

I think I've found the answer (myself). But I'm not sure whether it's right or wrong.

Use handle in child component and useMatches in parent component.

First, export handle object.

// pages/about.tsx
export const handle = {
  pageTitle: 'About Us',
  pageDescription: 'Learn more about our history'
};

function AboutPage() {
  return <h2>Who are we</h2>
}

Then, useMatches in <Layout>

// layouts/Layout.tsx
import { Outlet, useMatches } from 'react-router';

export default function Layout() {
  const matches = useMatches();

  const childHandle = matches.filter((match) => match.handle);
  const { handle } = childHandle[0] || {};

  console.log(handle);
// {
//  pageTitle: 'About Us',
//  pageDescription: 'Learn more about our history'
// }

  return (
    <>
      <Navbar />
      {handle?.pageTitle && <h1>{handle.pageTitle}</h1>}
      {handle?.pageDescription && <p>{handle.pageDescription}</p>}
      <Outlet />
      <Footer />
    </>
  );
}

Ref: Sharing data between nested routes in Remix

1
  • This is the correct way as the Layout component in app/root only accepts a single children prop with the component or error boundary of the root Commented Apr 15 at 7:56

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.