Skip to content
Last updated

Customize the root layout

Plans:ProScaleEnterprise

The RootLayout component renders the navbar, the page content, and the footer on every page of your project. Eject it when you need to add an element to every page, or to change the element that wraps the page.

If you only need to add React providers, eject the CustomContexts component instead. It is a smaller file, and your project keeps the updates Redocly makes to the layout.

Before you eject

Most page-level changes have a simpler option:

  • To display an announcement at the top of pages, use the banner option.
  • To hide the navbar or the footer, on all pages or on one page, use navbar.hide or footer.hide.
  • To change what the navbar or the footer contains, eject the Navbar or the Footer component.
  • To change the content area of a page, use custom page templates.
  • To add React providers, eject the CustomContexts component.

Wrap the root layout

To add an element to every page, wrap the RootLayout instead of ejecting it. Your project keeps the updates Redocly makes to the layout, and your file stays short.

Create the component you want to add, such as a SupportButton in the @theme/components folder. Then create the layout file yourself, and import the original component under a different name:

@theme/layouts/RootLayout.tsx
import React from 'react';
import { RootLayout as OriginalRootLayout } from '@redocly/theme/layouts/RootLayout';

import { SupportButton } from '../components/SupportButton';

export function RootLayout(props: React.ComponentProps<typeof OriginalRootLayout>) {
  return (
    <>
      <OriginalRootLayout {...props} />
      <SupportButton />
    </>
  );
}

The SupportButton component now renders on every page.

Some components read browser state, such as window or localStorage. Load those with the dynamic helper from @redocly/theme and the ssr: false option. The component then renders only in the browser.

Eject the root layout

Eject the RootLayout when you need to change the element that wraps the page, or the order of the parts inside it.

To eject the RootLayout in Redocly:

  1. In the Theme components panel, navigate to the layouts folder.
  2. Click the eject icon next to RootLayout.tsx.

The Redocly platform and the CLI put the ejected component in the @theme/layouts folder. Keep the component name, and keep the CustomContexts component around the page. If you remove CustomContexts, ejecting it has no effect on your project, because nothing renders it.

The following example adds a class to the element that wraps the page, and keeps the rest of the ejected file as is. The class lets you style the landing page and the documentation pages differently:

@theme/layouts/RootLayout.tsx
import React, { Suspense } from 'react';
import { useLocation } from 'react-router';

import type { JSX } from 'react';

import { Navbar } from '@redocly/theme/components/Navbar/Navbar';
import { Footer } from '@redocly/theme/components/Footer/Footer';
import { SkipContent } from '@redocly/theme/components/SkipContent/SkipContent';
import { AIAssistantButton } from '@redocly/theme/components/Buttons/AIAssistantButton';
import { useThemeHooks } from '@redocly/theme/core/hooks';
import { CustomContexts } from '@redocly/theme/layouts/CustomContexts';

export type LayoutConfig = {
  children: React.ReactNode;
};

export function RootLayout({ children }: LayoutConfig): JSX.Element {
  const { useSearchFeatures } = useThemeHooks();
  const { askAi } = useSearchFeatures();
  const { pathname } = useLocation();

  return (
    <div
      data-component-name="layouts/RootLayout"
      className={pathname === '/' ? 'landing-page' : 'documentation-page'}
    >
      <CustomContexts>
        <SkipContent />
        <Suspense>
          <Navbar />
        </Suspense>
        {children}
        <Suspense>
          <Footer />
        </Suspense>
        {askAi && <AIAssistantButton />}
      </CustomContexts>
    </div>
  );
}

Add the styles for the two classes to your theme stylesheet.

Resources