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

[WIP] Move route data to Astro.locals #2390

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft

Conversation

delucis
Copy link
Member

@delucis delucis commented Sep 22, 2024

Description

  • Early draft PR exploring moving Starlight’s route data object to Astro.locals — currently this is passed down via Astro.props to all our templating components.

  • There are some tricky nuances here for sure.

  • For example, middleware runs for all routes on a site, which can include non Starlight pages. For these we can’t generate route data. For now I’ve reflected this in the types for locals and asserted Astro.locals.routeData! in the components. There’s not really a sensible way to guard that without duplicating a null check in every component, but also it feels like route data should be defined in all cases where Starlight’s <Page> is rendered.

  • The <StarlightPage> component poses some challenges. Right now you pass some props and it generates route data. I’ve hacked this in by assigning that generated data to locals inside the component for now, but this does mean you can’t transform data for pages created this way with additional middleware. Not sure there’s any way to solve this?

    • One way might be to have a dedicated system of “route data middleware” implemented at the Starlight level instead of using generic Astro middleware, e.g.

      starlight({
        routeMiddleware: './some-file.ts',
      })

      We could bundle those in a virtual module and have both Starlight’s locals.ts and <StarlightPage> use them or something:

      context.locals.routeData = await useRouteData(context);
      for (const fn of routeMiddleware) {
        context.locals.routeData = fn(context.locals.routeData);
      }
  • The current branch rips out the prop drilling entirely. That means any overrides that rely on Astro.props will break. Could it be worth doing something to ease migration? Deprecate props but keep them around? Throw an error something like we did for labels? Something to think about.

  • There’s probably a tidier way to do some of the code — just did the quick and easy thing for now. (For example, Content is currently typed as optional in the route data object to make it easy to throw it in where I needed it, without checking all the places that type is used. But could probably tidy that up to have a dedicated separate type.)

  • Can also discuss naming here. So far it’s Astro.locals.routeData, but there’s probably an argument for something a bit more descriptive like Astro.locals.starlightRoute or even just Astro.locals.starlight potentially.

Copy link

changeset-bot bot commented Sep 22, 2024

⚠️ No Changeset found

Latest commit: 34129ab

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@github-actions github-actions bot added the 🌟 core Changes to Starlight’s main package label Sep 22, 2024
Copy link

netlify bot commented Sep 22, 2024

Deploy Preview for astro-starlight ready!

Name Link
🔨 Latest commit 34129ab
🔍 Latest deploy log https://app.netlify.com/sites/astro-starlight/deploys/6713ab4e347e0b00081e8469
😎 Deploy Preview https://deploy-preview-2390--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 (no change from production)
Accessibility: 100 (no change from production)
Best Practices: 100 (no change from production)
SEO: 92 (no change from production)
PWA: -
View the detailed breakdown and full score reports

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

@astrobot-houston
Copy link
Collaborator

astrobot-houston commented Sep 22, 2024

size-limit report 📦

Path Size
/index.html 6.15 KB (0%)
/_astro/*.js 22.36 KB (0%)
/_astro/*.css 13.73 KB (0%)

@delucis delucis added the 🌟 minor Change that triggers a minor release label Sep 22, 2024
@lorenzolewis
Copy link
Contributor

Really exciting to see this!

The current branch rips out the prop drilling entirely. That means any overrides that rely on Astro.props will break. Could it be worth doing something to ease migration? Deprecate props but keep them around? Throw an error something like we did for labels? Something to think about.

With the i18n update didn't we have a somewhat breaking change (possibly that's the labels update you're talking about)? I feel like if it's at all possible to keep current behavior around and mark it as depreciated then it would be much more helpful. This change will probably impact A LOT of users who have spent time crafting component overrides.

Can also discuss naming here. So far it’s Astro.locals.routeData, but there’s probably an argument for something a bit more descriptive like Astro.locals.starlightRoute or even just Astro.locals.starlight potentially.

Is there any norm here in Astro-land for 3rd party integrations? This has a potential for name collisions if a user has implemented middleware, correct? If that's the case then I think it would be good to at the very least prefix any locals with starlight.

@HiDeoo
Copy link
Member

HiDeoo commented Sep 23, 2024

Sharing a few quick thoughts before I forget them as I've been playing with the idea locally too and we can discuss more in depth later.

For now I’ve reflected this in the types for locals and asserted Astro.locals.routeData! in the components.

As this impacts components and not user components, I've been experimenting with a getter function instead that throws if the route data is not available, which would mean it was called in a non-Starlight route.

The <StarlightPage> component poses some challenges.

Definitely a tricky one indeed, been trying a few things but haven't found something that I'm happy with yet too.

Deprecate props but keep them around? Throw an error something like we did for labels?

As we have seen from the 0.28.0 reports, it's relatively easy to craft explicit errors for Astro.props.* usage in user code altho it gets confusing for users when it's coming from a plugin.

If we compare to labels, in a panel of 15 plugins, only 3 where using Astro.props.labels so the impact was pretty low. This would definitely not be the case for all other props. Still need to think about this one but if we go with the same approach as labels, we should make sure to mention it in the changeset/breaking change that users should make sure their plugins are up to date (which is something I didn't think about for labels).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🌟 core Changes to Starlight’s main package 🌟 minor Change that triggers a minor release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants