🌟 The Starlight Plugin
The Starlight Plugin from the Bag of Tricks adds view transitions to your Starlight site, bringing smooth animations and a touch of magic to every page change. If you only want standard cross-fade view transitions, do not install the plugin but do this.
See what the plugin did↗ to the Starlight Starter!Contents
- Installation
- Curious About the Details?
- How to Expect Content without the Plugin
- Simple alternative: Just Whole-Viewport Cross-Fade
Installation
Add view transitions to your existing Starlight site in two simple steps:
1. Install astro-vtbot from npm
cd .../my-starlight-projectnpm install -D astro-vtbot
2. Add the plugin to your astro.config file.
import { defineConfig } from 'astro/config';import { viewTransitions } from "astro-vtbot/starlight-view-transitions";
export default defineConfig({ integrations: [ starlight({ plugins: [viewTransitions()], ... ...})]})
Optional Steps
You can customize the plugin with additional behavior. These steps are all optional:
- enable the
renderBlocking
field in the frontmatter. - have an automatic fallback at the end of the markdown content if
renderBlocking
isn’t specified. - set config strings for the included scripts
Option 1: Enable the renderBlocking
field for use in the frontmatter
The Starlight Plugin provides an easy way to define expect links using a frontmatter filed called renderBlocking
. If you do not use this option, you can alternatively use Starlight’s head fields to define such links.
If you want to use the renderBlocking
attribute in the markdown frontmatter to tell the browser to wait for a fragment identifier “below the fold”, you need to extend Starlight’s content config.
import { defineCollection, z } from 'astro:content';import { docsLoader } from '@astrojs/starlight/loaders';import { docsSchema } from '@astrojs/starlight/schema';
export const collections = { docs: defineCollection({ loader: docsLoader(), schema: docsSchema( {extend: z.object({renderBlocking: z.string().optional()})} ) }),};
After that, you can set the renderBlocking
attribute in your frontmatter
renderBlocking: my-below-the-fold-heading
and the Starlight plugin will automatically add
<link rel="expect" href="#my-below-the-fold-heading" blocking="render" />
to the <head>
of your page.
Option 2: Automatically wait for the whole markdown section (if renderBlocking
isn’t defined)
If this option is enabled, the Starlight Plugin will automatically add the end-of-markdown
id…at the end of the markdown. If you do note enable the renderBlocking
option above or do not define a renderBlocking
id on a page, the plugin will automatically insert a render blocking link for you.
<link rel="expect" href="#end-of-markdown" blocking="render" />
So view transitions will not start until the whole content of your page is loaded. This can be convenient for small pages, but might also come with some performance penalties for larger content.
To enable this option, import and include the remarkEndOfMarkdown plugin:
import { defineConfig } from 'astro/config';import { viewTransitions, remarkEndOfMarkdown } from "astro-vtbot/starlight-view-transitions";
export default defineConfig({ markdown: { remarkPlugins: [remarkEndOfMarkdown] } integrations: [ starlight({ plugins: [viewTransitions()], ... ...})],})
Option 3: Set config strings for included scripts
Under the hood, the Starlight Plugin installs some of the @vtbag
scripts. Those can be configured by setting fields of the plugin’s options object:
Option | Package | Script | Script Option |
---|---|---|---|
allPages | turn-signal | index,debug,direction | data-selector↗ |
directionTypes | turn-signal | index,debug,directions | data-direction-types↗ |
directionAttribute | turn-signal | index,debug,directions | data-direction-attribute↗ |
declarativeNames | utensil-drawer | declarative-names | data-vtbag-decl↗ |
camShaftNames | cam-shaft | index | data-view-transition-names↗ |
For example, if you want to assign view transition names to all <h2>
headings you would instruct the declarative-names script like so:
starlight({ plugins: [viewTransitions({ declarativeNames: "h2 = heading2-" })], ......})
Curious About the Details?
Want to see all the magic this plugin brings? Head over to vtbag.dev for the fifth episode of Fun With View Transitions: Adding View Transitions to Your Starlight Site↗.
How to Expect Content without the Plugin
Of course you can alternatively create the head entry independent of vtbot by using Starlight’s frontmatter head
field
head: - tag: link attrs: rel: "expect" href: "#my-below-the-fold-heading" blocking: "render"
or Starlight’s global head
option:
import viewTransitions from 'astro-vtbot/starlight-view-transitions'export default defineConfig({ integrations: [ starlight({ plugins: [viewTransitions()], head: [{ tag: "link", attrs: { rel: "expect", href: "#below-the-fold", blocking: "render" } }] ... ...})]})
The global head option works particularly well if you define an id for the main content area or an element below the markdown content. To do this, you have to override Starlight components↗ to set the id, for example:
---import Default from "@astrojs/starlight/components/MarkdownContent.astro";---<Default><slot /></Default><div id="vtbag-below-the-fold" />
Simple alternative: Just Whole-Viewport Cross-Fade
If you just want a whole-viewport cross-fade effect on your Starlight site and none of the spiffy thrills of the plugin, you can alternatively add the following CSS to a custom CSS↗ file and be all set.
@media (prefers-reduced-motion: no-preference) { @view-transition { navigation: auto; }}