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.
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.
Layout | Usage | Default configuration |
---|---|---|
page | A page with a table of contents sidebar and content area. This layout is used by tutorials and guides. |
|
example | A page with a content area (and optional table of contents) sidebar. This layout is used by example pages. |
|
exampleIndex | This layout builds a homepage for an examples section. It organizes each example using the Cards component and displays a filter. |
|
full | This layout does not have a sidebar or standard content area. This layout is used for building a custom 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.
You can set any of the following frontMatter
props from the frontmatter in your page to override a feature:
frontMatter prop | Description | Conditions |
---|---|---|
layout | One of: page , example , full , exampleIndex . | |
navOrder | If 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. | |
order | Defined by number, the order that pages should appear in the sidebar's NavigationAccordion | page layout |
hideTitle | Hide the title of the page. | |
hideFeedback | Remove the feedback component from the bottom of the page. | |
sidebarTheme | Mapbox Assembly class names to style the sidebar container. | all layouts except none |
hideCardLanguage | If true , hide the language from all Cards. | exampleIndex layout |
hideCardDescription | If true , hide the description from all Cards. | exampleIndex layout |
fullWidthCards | Makes CardContainer full width. | exampleIndex layout |
showCards | Enable or disable the CardsContainer . This is helpful for pages like the dr-ui Components page. | exampleIndex layout |
cardColSize | A number to define the column sizes for the Cards | exampleIndex layout |
unProse | If true , remove the "prose" class from PageLayout. This is helpful for non-content pages. | |
noShellHeaderBuffer | If true , remove the header buffer div. This is helpful for custom headers like on the Help page. | |
hideFromNav | If true , remove an item from appearing in NavigationAccordion. (This is used in API docs.) | |
hideBreadcrumbs | If true , remove the breadcrumbs. (This is used by Help home page.) | |
hideSidebar | If 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 ). | |
showFilters | All 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 |
onThisPage | If 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. |
Prop | Type | Required |
---|---|---|
headings | array | FALSE |
navOrder | number | FALSE |
order | number | FALSE |
layout | enum [{"value":"'page'","computed":false},{"value":"'example'","computed":false},{"value":"'exampleIndex'","computed":false},{"value":"'full'","computed":false}] | FALSE |
hideTitle | bool | FALSE |
hideFeedback | bool | FALSE |
sidebarTheme | string | FALSE |
showCards | bool | FALSE |
fullWidthCards | bool | FALSE |
cardColSize | string | FALSE |
unProse | bool | FALSE |
noShellHeaderBuffer | bool | FALSE |
hideFromNav | bool | FALSE |
hideCardLanguage | bool | FALSE |
hideCardDescription | bool | FALSE |
hideBreadcrumbs | bool | FALSE |
hideSidebar | bool | FALSE |
title | string | FALSE |
showFilters | arrayOf {"name":"enum","computed":true,"value":"filterOptions"} | FALSE |
onThisPage | bool | FALSE |
groupOrder | number | FALSE |
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
}}
/>
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
:
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
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.
PageLayout
propsThe PageLayout
component accepts the following props for you to further customize your site:
Prop | Type | Description |
---|---|---|
filters | objectOf ["name","value"] | An object of filters. This dataset can be generated with @mapbox/dr-ui/helpers/batfish/filters.js. |
constants | shape ["SITE","BASEURL","FORWARD_EVENT_WEBHOOK"] |
|
AppropriateImage | func | Required if using the |
headings | array | For when headings are dynamic, this is used by API docs |
feedbackSentryDsn | union ["0","1"] | For |
domain | shape ["title","path"] | The domain's title and homepage path to be added as the first Breadcrumb link |
hideSearch | bool | 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.
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
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:
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
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.
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>
);
}
}