Skip to content

Commit

Permalink
Support component customisation (#709)
Browse files Browse the repository at this point in the history
Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
Co-authored-by: HiDeoo <494699+HiDeoo@users.noreply.github.com>
  • Loading branch information
3 people committed Oct 6, 2023
1 parent 903a579 commit 140e729
Show file tree
Hide file tree
Showing 59 changed files with 1,683 additions and 527 deletions.
21 changes: 21 additions & 0 deletions .changeset/plenty-donkeys-lay.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
'@astrojs/starlight': minor
---

Add support for overriding Starlight’s built-in components

⚠️ **BREAKING CHANGE** — The page footer is now included on pages with `template: splash` in their frontmatter. Previously, this was not the case. If you are using `template: splash` and want to continue to hide footer elements, disable them in your frontmatter:

```md
---
title: Landing page
template: splash
# Disable unwanted footer elements as needed
editUrl: false
lastUpdated: false
prev: false
next: false
---
```

⚠️ **BREAKING CHANGE** — This change involved refactoring the structure of some of Starlight’s built-in components slightly. If you were previously overriding these using other techniques, you may need to adjust your code.
133 changes: 133 additions & 0 deletions docs/src/content/docs/guides/overriding-components.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
---
title: Overriding Components
description: Learn how to override Starlight’s built-in components to add custom elements to your documentation site’s UI.
sidebar:
badge: New
---

Starlight’s default UI and configuration options are designed to be flexible and work for a range of content. Much of Starlight's default appearance can be customized with [CSS](/guides/css-and-tailwind/) and [configuration options](/guides/customization/).

When you need more than what’s possible out of the box, Starlight supports building your own custom components to extend or override (completely replace) its default components.

## When to override

Overriding Starlight’s default components can be useful when:

- You want to change how a part of Starlight’s UI looks in a way not possible with [custom CSS](/css-and-tailwind/).
- You want to change how a part of Starlight’s UI behaves.
- You want to add some additional UI alongside Starlight’s existing UI.

## How to override

1. Choose the Starlight component you want to override.
You can find a full list of components in the [Overrides Reference](/reference/overrides/).

This example will override Starlight’s [`SocialIcons`](/reference/overrides/#socialicons) component in the page nav bar.

2. Create an Astro component to replace the Starlight component with.
This example renders a contact link.

```astro
---
// src/components/EmailLink.astro
import type { Props } from '@astrojs/starlight/props';
---
<a href="mailto:houston@example.com">E-mail Me</a>
```

3. Tell Starlight to use your custom component in the [`components`](/reference/configuration/#components) configuration option in `astro.config.mjs`:

```js {9-12}
// astro.config.mjs
import { defineConfig } from 'astro/config';
import starlight from '@astrojs/starlight';

export default defineConfig({
integrations: [
starlight({
title: 'My Docs with Overrides',
components: {
// Override the default `SocialLinks` component.
SocialIcons: './src/components/EmailLink.astro',
},
}),
],
});
```

## Reuse a built-in component

You can build with Starlight’s default UI components just as you would with your own: importing and rendering them in your own custom components. This allows you to keep all of Starlight's basic UI within your design, while adding extra UI alongside them.

The example below shows a custom component that renders an e-mail link along with the default `SocialLinks` component:

```astro {4,8}
---
// src/components/EmailLink.astro
import type { Props } from '@astrojs/starlight/props';
import Default from '@astrojs/starlight/SocialIcons.astro';
---
<a href="mailto:houston@example.com">E-mail Me</a>
<Default {...Astro.props}><slot /></Default>
```

When rendering a built-in component inside a custom component:

- Spread `Astro.props` into it. This makes sure that it receives all the data it needs to render.
- Add a [`<slot />`](https://docs.astro.build/en/core-concepts/astro-components/#slots) inside the default component. This makes sure that if the component is passed any child elements, Astro knows where to render them.

## Use page data

When overriding a Starlight component, your custom implementation receives a standard `Astro.props` object containing all the data for the current page.
This allows you to use these values to control how your component template renders.

For example, you can read the page’s frontmatter values as `Astro.props.entry.data`. In the following example, a replacement [`PageTitle`](/reference/overrides/#pagetitle) component uses this to display the current page’s title:

```astro {5} "{title}"
---
// src/components/Title.astro
import type { Props } from '@astrojs/starlight/props';
const { title } = Astro.props.entry.data;
---
<h1 id="_top">{title}</h1>
<style>
h1 {
font-family: 'Comic Sans';
}
</style>
```

Learn more about all the available props in the [Overrides Reference](/reference/overrides/#prop-types).

### Only override on specific pages

Component overrides apply to all pages. However, you can conditionally render using values from `Astro.props` to determine when to show your custom UI, when to show Starlight’s default UI, or even when to show something entirely different.

In the following example, a component overriding Starlight's [`Footer`](/reference/overrides/#footer-1) displays "Built with Starlight 🌟" on the homepage only, and otherwise shows the default footer on all other pages:

```astro
---
// src/components/ConditionalFooter.astro
import type { Props } from '@astrojs/starlight/props';
import Default from '@astrojs/starlight/Footer.astro';
const isHomepage = Astro.props.slug === '';
---
{
isHomepage ? (
<footer>Built with Starlight 🌟</footer>
) : (
<Default {...Astro.props}>
<slot />
</Default>
)
}
```

Learn more about conditional rendering in [Astro’s Template Syntax guide](https://docs.astro.build/en/core-concepts/astro-syntax/#dynamic-html).
2 changes: 0 additions & 2 deletions docs/src/content/docs/guides/sidebar.mdx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
---
title: Sidebar Navigation
description: Learn how to set up and customize your Starlight site’s sidebar navigation links.
sidebar:
badge: New
---

import FileTree from '../../../components/file-tree.astro';
Expand Down
2 changes: 2 additions & 0 deletions docs/src/content/docs/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ head:
content: Starlight 🌟 Build documentation sites with Astro
description: Starlight helps you build beautiful, high-performance documentation websites with Astro.
template: splash
editUrl: false
lastUpdated: false
banner:
content: |
<span class="ph-banner">
Expand Down
16 changes: 16 additions & 0 deletions docs/src/content/docs/reference/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -436,3 +436,19 @@ Sets the delimiter between page title and site title in the page’s `<title>` t

By default, every page has a `<title>` of `Page Title | Site Title`.
For example, this page is titled “Configuration Reference” and this site is titled “Starlight”, so the `<title>` for this page is “Configuration Reference | Starlight”.

### `components`

**type:** `Record<string, string>`

Provide the paths to components to override Starlight’s default implementations.

```js
starlight({
components: {
SocialLinks: './src/components/MySocialLinks.astro',
},
});
```

See the [Overrides Reference](/reference/overrides/) for details of all the components that you can override.

0 comments on commit 140e729

Please sign in to comment.