All docschevron-rightDr. UIchevron-rightarrow-leftGuideschevron-rightPageLayout component

PageLayout component

The PageLayout component is the main controller for building pages with Dr. UI and offers five layout options. PageLayout provides everything from the site's navigation, to the sidebar contents, and main content area. It also includes common components like Search and Feedback.

While the docs-starter-kit configures PageLayout with the most common setup, this guide describes all available options to working and customizing the component.

Layouts

The PageLayout component comes with several layouts that you define in your page's frontmatter. Each layout is a set of opinionated configurations, but you have the option to customize the layout by setting additional frontmatter fields.

LayoutUsageDefault configuration
pageA page with a table of contents sidebar and content area. This layout is used by tutorials and guides.
{
  "sidebarTheme": "",
  "onThisPage": true
}
exampleA page with a content area (and optional table of contents) sidebar. This layout is used by example pages.
exampleIndexThis layout builds a homepage for an examples section. It organizes each example using the Cards component and displays a filter.
{
  "aside": "none",
  "showCards": true,
  "hideFeedback": true
}
fullThis layout does not have a sidebar or standard content area. This layout is used for building a custom layout.
{
  "aside": "none"
}

How do I set a layout?

In the frontmatter of the page, set the field layout to a valid layout value.

Example:

layout: page

The remark-lint-mapbox/frontmatter linter will help assert that every markdown page has a valid layout.

How can I customize the layout?

You can set any of the following frontMatter props from the frontmatter in your page to override a feature:

frontMatter propDescriptionConditions
layoutOne of: page, example, full, exampleIndex.
navOrderIf defined with a number, the page will be added to TabList in the navigation bar. This is the canonical way for defining a top-level page.
orderDefined by number, the order that pages should appear in the sidebar's NavigationAccordionpage layout
hideTitleHide the title of the page.
hideFeedbackRemove the feedback component from the bottom of the page.
sidebarThemeMapbox Assembly class names to style the sidebar container.all layouts except none
hideCardLanguageIf true, hide the language from all Cards.exampleIndex layout
hideCardDescriptionIf true, hide the description from all Cards.exampleIndex layout
fullWidthCardsMakes CardContainer full width.exampleIndex layout
showCardsEnable or disable the CardsContainer. This is helpful for pages like the dr-ui Components page.exampleIndex layout
cardColSizeA number to define the column sizes for the CardsexampleIndex layout
unProseIf true, remove the "prose" class from PageLayout. This is helpful for non-content pages.
noShellHeaderBufferIf true, remove the header buffer div. This is helpful for custom headers like on the Help page.
hideFromNavIf true, remove an item from appearing in NavigationAccordion. (This is used in API docs.)
hideBreadcrumbsIf true, remove the breadcrumbs. (This is used by Help home page.)
hideSidebarIf true, remove the sidebar. (This is used by Help home page and Playground.). This setting will also enable breadcrumbs to display on mobile (unless hideBreadcrumbs: true).
showFiltersAll filters for an exampleIndex page are shown if the data is available. Use showFilters to define only the filters you want the page to display.exampleIndex layout
onThisPageIf unspecified, <OnThisPage> aside will appear on all pages with layout: page. If set to false for pages with layout: page, <OnThisPage> will be hidden. If set to true for pages with other layouts, <OnThisPage> will appear.
See prop table
PropTypeRequired
headingsarray FALSE
navOrdernumber FALSE
ordernumber FALSE
layoutenum [{"value":"'page'","computed":false},{"value":"'example'","computed":false},{"value":"'exampleIndex'","computed":false},{"value":"'full'","computed":false}]FALSE
hideTitlebool FALSE
hideFeedbackbool FALSE
sidebarThemestring FALSE
showCardsbool FALSE
fullWidthCardsbool FALSE
cardColSizestring FALSE
unProsebool FALSE
noShellHeaderBufferbool FALSE
hideFromNavbool FALSE
hideCardLanguagebool FALSE
hideCardDescriptionbool FALSE
hideBreadcrumbsbool FALSE
hideSidebarbool FALSE
titlestring FALSE
showFiltersarrayOf {"name":"enum","computed":true,"value":"filterOptions"}FALSE
onThisPagebool FALSE
groupOrdernumber FALSE

How can I set defaults for multiple pages or an entire site?

When you create your PageLayout component in your site's page shell, you can define or redefine the frontmatter object.

The example below will turn off the feedback component for every page:

<PageLayout
  frontMatter={{
    ...this.props.frontMatter,
    hideFeedback: true
  }}
/>

Filters and navigation

The PageLayout component accepts filters and navigation props to define all the filters for examples and the site's navigation system, respectively.

In most cases, you can use Batfish helpers to automatically generate this dataset. See the following resources on how to install these functions and use them with PageLayout:

Filters

By default an examplesIndex layout page (or example layout with navOrder), will display the cards for all sub pages. Filters for products, topics, languages, levels, and videos will appear if the group of sub pages has at least two options for each filter category.

If you would like to remove a filter from the exampleIndex page, use the showFilters frontMatter property to list the filters that you want. The following example will only show filters for products and levels:

showFilters:
  - products
  - levels

Available values for showFilters: products, topics, languages, level, videos, search

Multi-structured sites

Most docs.mapbox.com sites use a single structure, which means it documents a single product. But iOS and Android use a multi-structure to document maps, navigation, and search.

The navigation Batfish helper function can handle multi-structured sites and build the navigation dataset required for PageLayout automatically. You will need to include a configuration object to define each part of the site. See shape of multi-structured sections for how to write a configuration object.

See the Multi-structured guide for steps on building a new site.

Other PageLayout props

The PageLayout component accepts the following props for you to further customize your site:

PropTypeDescription
filtersobjectOf ["name","value"]

An object of filters. This dataset can be generated with @mapbox/dr-ui/helpers/batfish/filters.js.

constantsshape ["SITE","BASEURL","FORWARD_EVENT_WEBHOOK"]
  • SITE - the name of the site.
  • BASEURL - the base url of the website, as used in the batfish.config.js
  • FORWARD_EVENT_WEBHOOK - an object with to values: production and staging.
AppropriateImagefunc

Required if using the exampleIndex layout along with imageIds. The value is the local AppropriateImage component.

headingsarray

For when headings are dynamic, this is used by API docs

feedbackSentryDsnunion ["0","1"]

For Feedback component

domainshape ["title","path"]

The domain's title and homepage path to be added as the first Breadcrumb link

hideSearchbool

Hide Search component from the sidebar

The site navigation appears at the left side of every page. It uses ProductMenu to show the site title, and NavigationAccordion to display all navigation links for the site starting with top-level pages.

What are top-level pages?

Top-level pages are a small set of pages that define a section of the site. These pages build the content hierarchy and act as a homepage for each section. The hierarchy is also important for telling NavigationAccordion which section the user is now on.

For example, this page falls under Guides, a top-level page. Since you're visiting a page under the Guide's section, the Guides link in the NavigationAccordion is styled slightly differently to help show you where you are on the site.

Top-level pages almost always follow the folder structure in src/pages/. For example a site with the following folder structure likely uses examples/index.md, help/index.md, and overview/index.md as its top-level pages:

src/
  pages/
    examples/
      index.md
      clustering.md
      markers.md
    help/
      index.md
    overview/
      index.md

How do I define top-level pages for a site?

You can define a top-level page by adding navOrder: 1 to the frontmatter of the desired pages. Increment the number to reflect the order you want them to appear in the navigation bar. Once updated, these pages will automatically populate the navigation bar.

Things to consider:

  • Your site must have at least one top-level page.
  • If your site requires more than four top-level pages, you should reconsider the information architecture of the site.
  • When developing locally, you may need to restart your local server to see the changes reflected in the site.
book
NOTE

The frontmatter props navOrder and order have different functions.

  • navOrder identifies a top-level page and its position in the NavigationAccordion across the top of the page.
  • order sets the order for all pages in a section that uses the page layout.

For top-level pages using the page layout, besides setting navOrder, you will also set order: 1 to make sure that the top-level page appears first in the NavigationAccordion

Overview header

The main page for each docs site displays the OverviewHeader to orient the user to the product.

To add OverviewHeader to your page, pass the props of the component in the frontMatter under overviewHeader.

overviewHeader:
  title: 'Dr. UI'
  features:
    - 'React components to build documentation sites'
    - 'Support for all modern browsers'
  changelogLink: /dr-ui/changelog/
  installLink: https://github.com/mapbox/dr-ui/blob/main/README.md
  ghLink: https://github.com/mapbox/dr-ui

To include dynamic variables, such as version or use the AppropriateImage component for the value of image, update the frontMatter prop in site's PageLayout component (found in page-shell.js).

The following example is the value of the frontMatter prop which overrides the values of version and image in the overviewHeader frontMatter prop object:

{
  ...frontMatter,
  ...frontMatter.overviewHeader && {
      overviewHeader: {
        ...frontMatter.overviewHeader,
        version: myVariable,
        image: <AppropriateImage alt="" id="documentation-astronaut" />
      }
    }
  })
}

This technique may also be used by multi-structured sites, although you'll need to add logic to help determine which version constant to use.

Custom aside

Sites like Mapbox GL JS require custom asides since the data is derived from multiple sources. Similarly, the Dr. UI components page also uses a custom aside, see the example below for how to conditionally display a custom sidebar:

import Aside from './aside';

class PageShell extends React.Component {
  render() {
    const { location } = this.props;
    return (
      <PageLayout
        customAside={location.pathname === '/dr-ui/' ? <Aside /> : undefined}
      >
        {children}
      </PageLayout>
    );
  }
}
Was this page helpful?