Skip to content

Autogenerated link custom attributes#3266

Merged
delucis merged 9 commits intowithastro:mainfrom
HiDeoo:hd-feat-autogenerate-attrs
Jul 16, 2025
Merged

Autogenerated link custom attributes#3266
delucis merged 9 commits intowithastro:mainfrom
HiDeoo:hd-feat-autogenerate-attrs

Conversation

@HiDeoo
Copy link
Copy Markdown
Member

@HiDeoo HiDeoo commented Jul 1, 2025

Description

This PR adds support for custom HTML attributes on autogenerated sidebar links using the autogenerate.attrs option.

  • The autogenerate.attrs is used rather than just attrs as attrs is only supported for links and not groups at the moment. This could be confusing to support attrs on autogenerated groups but not on manually defined groups, so autogenerate.attrs is used to clarify that this is only for links in an autogenerated groups.
  • Using attrs on sidebar groups now results in a type error on top of the existing runtime error. I added some type tests to ensure this is the case.
  • Individual pages can override custom attributes using the sidebar.attrs frontmatter field.

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Jul 1, 2025

🦋 Changeset detected

Latest commit: 1041be1

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@astrojs/starlight Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@netlify
Copy link
Copy Markdown

netlify bot commented Jul 1, 2025

Deploy Preview for astro-starlight ready!

Name Link
🔨 Latest commit 1041be1
🔍 Latest deploy log https://app.netlify.com/projects/astro-starlight/deploys/6877aa330e9b34000891fe8b
😎 Deploy Preview https://deploy-preview-3266--astro-starlight.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
1 paths audited
Performance: 100 (🟢 up 17 from production)
Accessibility: 100 (no change from production)
Best Practices: 92 (no change from production)
SEO: 100 (no change from production)
PWA: -
View the detailed breakdown and full score reports

To edit notification comments on pull requests, go to your Netlify project configuration.

@github-actions github-actions bot added 📚 docs Documentation website changes 🌟 core Changes to Starlight’s main package labels Jul 1, 2025
@astrobot-houston
Copy link
Copy Markdown
Contributor

astrobot-houston commented Jul 1, 2025

Lunaria Status Overview

🌕 This pull request will trigger status changes.

Learn more

By default, every PR changing files present in the Lunaria configuration's files property will be considered and trigger status changes accordingly.

You can change this by adding one of the keywords present in the ignoreKeywords property in your Lunaria configuration file in the PR's title (ignoring all files) or by including a tracker directive in the merged commit's description.

Tracked Files

Locale File Note
en guides/sidebar.mdx Source changed, localizations will be marked as outdated.
en reference/configuration.mdx Source changed, localizations will be marked as outdated.
en reference/frontmatter.md Source changed, localizations will be marked as outdated.
Warnings reference
Icon Description
🔄️ The source for this localization has been updated since the creation of this pull request, make sure all changes in the source have been applied.

@alvinometric
Copy link
Copy Markdown
Contributor

🥳 Amazing !

route.entry.data.sidebar.label || route.entry.data.title,
route.entry.data.sidebar.badge,
route.entry.data.sidebar.attrs
Object.keys(route.entry.data.sidebar.attrs).length > 0 ? route.entry.data.sidebar.attrs : attrs
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if some people would expect the attrs to be combined rather than overridden? Like if you have autogenerate: { attrs: { 'data-special': true } } and then within that a page with frontmatter like:

sidebar:
  attrs:
    class: experimental

Would you expect to get a <a data-special class="experimental">?

The argument against is that it makes it a bit harder to remove attributes. I guess you’d need something like this to remove an attribute:

sidebar:
  attrs:
    data-special:

Assuming something like this:

Suggested change
Object.keys(route.entry.data.sidebar.attrs).length > 0 ? route.entry.data.sidebar.attrs : attrs
{ ...attrs, ...route.entry.data.sidebar.attrs }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch! I'd expect the attributes to be merged, with page-level attributes taking precedence over others.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question. When working on the PR, I actually tried both approaches and found the overriding one more to my liking in the scenarios I was testing but I can definitely see how when you expect one approach, the other can be confusing (that's also why I mentioned it explicitly in the docs).

Happy to update the PR if more people think merging is the better approach, I'll do that tomorrow morning.

Thanks for the feedback 🙌

Copy link
Copy Markdown
Member

@delucis delucis Jul 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind sharing a bit about the detail of those scenarios? I always like to hear the concrete use cases as it can help understand better. My thinking was mostly based on a scenario like:

  • autogenerate.attrs would be used for a unified control over a group of links, e.g. maybe these are your experimental docs, or reference, or some other category, and get a specific custom style to indicate that
  • sidebar.attrs would be used for adding additional attributes for a specific page link, e.g. to flag a new page perhaps
  • The group identity and the page-specific attributes aren’t necessarily exclusive: you’d want to keep both.

Admittedly, if that example was setting class for both, nothing would change here, because sidebar.attrs.class would still need to include the group class names, but for some other attributes it might make more sense, e.g. maybe there’s some group you set target="_blank" rel="noopener" for but don’t want to have to set those again in frontmatter just to add a class. (And to maintain — changes to the group config would need adding to all overridden pages and remembering that there are overridden pages.)

Open to convincing either way though — sounds like you had some specific scenarios in mind, so those might be valid.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My initial decision to override attributes was not really tied to the scenarios I tested but more to the overall experience when playing with them and overriding attributes at the page level:

  • I found overriding easier as I was starting from a blank state, and just having to focus on "what exactly do I want as custom attributes for this page?" vs "ok, I already have these attributes applied defined in another file, here is what I want in the end, what do I need to remove and add to get there?"
  • Removing attributes is not the obvious thing to do when merging attributes
  • One example I tried was with the style attributes while the configuration was applying a class attribute. I kinda liked that my custom class was automatically removed when I set a style attribute, as it was not relevant anymore.

I've updated the PR to use a merge strategy so that we can play with it more and see how it feels.

One small note, I had to allow null values to properly support removing attributes from the frontmatter:

sidebar:
  attrs:
    data-special:
    data-special: ~
    data-special: null

All of these would result in a null value which we were not previously allowing.

Co-authored-by: Chris Swithinbank <swithinbank@gmail.com>
Co-authored-by: Kevin Zuniga Cuellar <kzunigac@uvm.edu>
@delucis delucis added the 🌟 minor Change that triggers a minor release label Jul 11, 2025
HiDeoo and others added 2 commits July 11, 2025 19:18
Co-authored-by: Felix Schneider <99918022+trueberryless@users.noreply.github.com>
Co-authored-by: Felix Schneider <99918022+trueberryless@users.noreply.github.com>
Copy link
Copy Markdown
Member

@delucis delucis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for picking up this idea, implementing, and testing it so quickly! If you’re happy with the switch to the merge behaviour, then I think we can get this released this week.

Left one small nit on the docs, but the code and tests look great 🚀

@delucis delucis added the ✅ approved Pull requests that have been approved and are ready to merge when next cutting a release label Jul 14, 2025
@delucis delucis added this to the v0.35 milestone Jul 14, 2025
HiDeoo and others added 2 commits July 15, 2025 16:09
Co-authored-by: Chris Swithinbank <swithinbank@gmail.com>
@delucis delucis merged commit 1161af0 into withastro:main Jul 16, 2025
16 checks passed
@astrobot-houston astrobot-houston mentioned this pull request Jul 16, 2025
Yoxnear pushed a commit to Yoxnear/starlight-custom that referenced this pull request Jul 23, 2025
Co-authored-by: Chris Swithinbank <swithinbank@gmail.com>
Co-authored-by: Kevin Zuniga Cuellar <kzunigac@uvm.edu>
Co-authored-by: Felix Schneider <99918022+trueberryless@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✅ approved Pull requests that have been approved and are ready to merge when next cutting a release 🌟 core Changes to Starlight’s main package 📚 docs Documentation website changes 🌟 minor Change that triggers a minor release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants