Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to customise Starlight’s components #415

Closed
1 task
dhruvkb opened this issue Jul 27, 2023 · 10 comments · Fixed by #709
Closed
1 task

Ability to customise Starlight’s components #415

dhruvkb opened this issue Jul 27, 2023 · 10 comments · Fixed by #709
Labels
enhancement Something it would be good to improve

Comments

@dhruvkb
Copy link
Contributor

dhruvkb commented Jul 27, 2023

What version of starlight are you using?

0.5.2

What is your idea?

The header of my docs site looks pretty sparse. I would like to add some glanceable information to it, like the latest release, GitHub stars etc., similar to this feature in the
Mkdocs/Material theme.

Screenshot 2023-07-27 at 8 27 10 AM

Why is this feature necessary?

The header is currently underutilised space. Top-level menus or custom widgets could make use of that space.

Do you have examples of this feature in other projects?

Material theme for Mkdocs https://squidfunk.github.io/mkdocs-material/

Participation

  • I am willing to submit a pull request for this issue.
@delucis
Copy link
Member

delucis commented Jul 27, 2023

Thanks for the issue! We’d like to enable this all over the layout, not just in the header, so yes, consider this on the roadmap 🥳

(Bear in mind though that while the header may seem underutilised on wider screens, it is less clear cut on narrow viewports like on mobile.)

@delucis delucis added the enhancement Something it would be good to improve label Jul 27, 2023
@dhruvkb
Copy link
Contributor Author

dhruvkb commented Jul 27, 2023

Yes, I agree that the current header works very well on mobile and the mobile version is by far the best I've seen in a docs theme so kudos!

I'm excited to see how this will be implemented and hopefully I can contribute in some way.

@khendrikse
Copy link

I'm also very interested in these possible changes :)! @delucis are there ways for people to contribute to this functionality by any chance?

@HiDeoo
Copy link
Member

HiDeoo commented Aug 2, 2023

Just for information, there is also a Discord thread where we started talking about possible APIs, different use-cases, what would be supported at first, what would not, etc. if some people are interested.

@delucis
Copy link
Member

delucis commented Aug 2, 2023

Thank you @HiDeoo and thanks for your interest @khendrikse! This is a good push for me to bring some of my notes from that thread over here for those who aren’t on Discord.

Would love to hear people’s thoughts, if this aligns with what you want and expect, and if there are use cases you have that this would or wouldn’t solve!

The idea

  • Users provide some kind of config to Starlight to tell us about custom components to use.
  • We import those and use them.
  • We provide a type for props that we guarantee to pass to components, most likely the same for every component, so it’s up to each component what it needs.

There are two use cases the system should support ideally:

  • I, a user, want to replace Starlight’s component X with my own component
  • I, a user, have a component I want to add but not replace built-in components

It’s possible the best approach for the latter is just to let people import and wrap our built-in components, but I’d like to check that’s true, because really the nicest for “slotting” things in is just to write your component and not need to worry about that.

Some API sketches

The API could maybe look something like this:

// astro.config.mjs

starlight({
  components: {
    // Component for a dedicated template area that is empty currently:
    SidebarFooter: './src/components/SidebarFooter.astro',
    // Component that overrides a built-in component:
    SocialIcons: './src/components/SocialIcons.astro',
  },
})

A user component could import a StarlightComponentProps to use for their props type. For cases where you override instead of slot in, like SocialIcons, you could maybe import and use the original:

---
// src/components/SocialIcons.astro

import {
  SocialIcons,
  type StarlightComponentProps
} from '@astrojs/starlight/layout-components';

type Props = StarlightComponentProps;
---
<SocialIcons {...Astro.props}>
  <ExtraIconAtStart slot="before" />
  <ExtraIconAtEnd slot="after" />
</SocialIcons>

Q&A

  • What if I want a component only on certain routes?.
    We would render your component on all routes. BUT you’d receive the current route in props and be able to to conditionally render inside your component based on that.
  • What if I want to use a React, Vue, etc. component?
    We would require your components to be Astro components. BUT these could include components from your client framework and any relevant client:* directives.

Example uses

  • I want to add support for a different search service to Starlight: I create a new component and replace Starlight’s built-in component.
  • I want to add an unsupported icon to my social links: I create a component that wraps Starlight’s default (see example above).
  • I want to programmatically filter which headings are displayed in the table of contents: I create a component that wraps Starlight’s default table of contents and filters out headings before passing it props.
  • I want to add a feedback mechanism to the footer of a page (e.g. Feelback): I slot my feedback component into a predefined empty “footer” slot in Starlight’s layout

@delucis delucis changed the title Ability to add custom components to the Header Ability to customise Starlight’s components Aug 2, 2023
@TheOtterlord
Copy link
Member

This looks awesome!
Maybe this extends to a separate issue, but could integrations access the config to define their own component overrides? For example, a search service integration/plugin that replaces the built-in search.

@delucis
Copy link
Member

delucis commented Aug 2, 2023

Maybe this extends to a separate issue, but could integrations access the config to define their own component overrides? For example, a search service integration/plugin that replaces the built-in search.

Yes. That will be out of scope for now. But one argument in favour of the config in this form is that we want to enable Starlight “plugins” further down the road and one thing they could do is provide component overrides via this. (Would be harder to do if component overrides were added via some naming convention or “magic” folder.)

@khendrikse
Copy link

@delucis This sounds really good. Especially because if I understand correctly it would also support anyone wishing to just extend the existing components.

Especially the footer feedback mechanism I think (and in a sense, any footer changes) will be a use case I imagine will be seen a lot.

@D3vil0p3r
Copy link
Contributor

Any news about this topic?

@stereobooster
Copy link

Related to sidebar issues:

what if instead extending config with attributes allow to generate sidebar based on collection:

const blogEntries = await getCollection('blog');
blogEntries.sort(...)

then people can add any metadata to collection and use it for sorting of for showing custom icons etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Something it would be good to improve
Projects
None yet
7 participants