Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .changeset/gold-sloths-unite.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
'@astrojs/starlight': minor
---

Makes `social` configuration more flexible.

⚠️ **BREAKING CHANGE:** The `social` configuration option has changed syntax. You will need to update this in `astro.config.mjs` when upgrading.

Previously, a limited set of platforms were supported using a shorthand syntax with labels built in to Starlight. While convenient, this approach was less flexible and required dedicated code for each social platform added.

Now, you must specify the icon and label for each social link explicitly and you can use any of [Starlight’s built-in icons](https://starlight.astro.build/reference/icons/) for social links.

The following example shows updating the old `social` syntax to the new:

```diff
- social: {
- github: 'https://github.com/withastro/starlight',
- discord: 'https://astro.build/chat',
- },
+ social: [
+ { icon: 'github', label: 'GitHub', href: 'https://github.com/withastro/starlight' },
+ { icon: 'discord', label: 'Discord', href: 'https://astro.build/chat' },
+ ],
```
8 changes: 4 additions & 4 deletions docs/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ export default defineConfig({
editLink: {
baseUrl: 'https://github.com/withastro/starlight/edit/main/docs/',
},
social: {
github: 'https://github.com/withastro/starlight',
discord: 'https://astro.build/chat',
},
social: [
{ icon: 'github', label: 'GitHub', href: 'https://github.com/withastro/starlight' },
{ icon: 'discord', label: 'Discord', href: 'https://astro.build/chat' },
],
head: [
{
tag: 'script',
Expand Down
5 changes: 1 addition & 4 deletions docs/src/components/social-links-type.astro
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
---
import { socialLinks } from '../../../packages/starlight/schemas/social';
const socials = [...socialLinks].sort((a, b) => a.localeCompare(b, 'en'));
---

<code>{`Partial<Record<${socials.map((social) => `'${social}'`).join(' | ')}, string>>`}</code>
<code set:text="Array<{ label: string; icon: string; href: string }>" />
23 changes: 16 additions & 7 deletions docs/src/content/docs/guides/customization.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -200,10 +200,15 @@ defineConfig({

Starlight has built-in support for adding links to your social media accounts to the site header via the [`social`](/reference/configuration/#social) option in the Starlight integration.

You can find a full list of supported link icons in the [Configuration Reference](/reference/configuration/#social).
Let us know on GitHub or Discord if you need support for another service!
Each entry in the `social` array must be an object with three properties:

```js {9-12}
- `icon`: one of Starlight’s [built-in icons](/reference/icons/), e.g. `"github"`.
- `label`: an accessible label for the link, e.g. `"GitHub"`.
- `href`: the URL for the link, e.g. `"https://github.com/withastro/starlight"`.

The following example adds links to the Astro Discord chat and the Starlight GitHub repository:

```js {9-16}
// astro.config.mjs
import { defineConfig } from 'astro/config';
import starlight from '@astrojs/starlight';
Expand All @@ -212,10 +217,14 @@ export default defineConfig({
integrations: [
starlight({
title: 'Docs With Social Links',
social: {
discord: 'https://astro.build/chat',
github: 'https://github.com/withastro/starlight',
},
social: [
{ icon: 'discord', label: 'Discord', href: 'https://astro.build/chat' },
{
icon: 'github',
label: 'GitHub',
href: 'https://github.com/withastro/starlight',
},
],
}),
],
});
Expand Down
29 changes: 11 additions & 18 deletions docs/src/content/docs/reference/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -341,28 +341,21 @@ The default locale will be used to provide fallback content where translations a

### `social`

import SocialLinksType from '~/components/social-links-type.astro';
**type:** <code>{`Array<{ label: string; icon: `}[StarlightIcon](/reference/icons/){`; href: string }>`}</code>

**type:** <SocialLinksType />

Optional details about the social media accounts for this site. Adding any of these will display them as icon links in the site header.
Optional details about the social media accounts for this site.
Each entry will be displayed as an icon link in the site header.

```js
starlight({
social: {
codeberg: 'https://codeberg.org/knut/examples',
discord: 'https://astro.build/chat',
github: 'https://github.com/withastro/starlight',
gitlab: 'https://gitlab.com/delucis',
linkedin: 'https://www.linkedin.com/company/astroinc',
mastodon: 'https://m.webtoo.ls/@astro',
threads: 'https://www.threads.net/@nmoodev',
twitch: 'https://www.twitch.tv/bholmesdev',
twitter: 'https://twitter.com/astrodotbuild',
'x.com': 'https://x.com/astrodotbuild',
youtube: 'https://youtube.com/@astrodotbuild',
},
});
social: [
{ icon: 'codeberg', label: 'Codeberg', href: 'https://codeberg.org/knut' },
{ icon: 'discord', label: 'Discord', href: 'https://astro.build/chat' },
{ icon: 'github', label: 'GitHub', href: 'https://github.com/withastro' },
{ icon: 'gitlab', label: 'GitLab', href: 'https://gitlab.com/delucis' },
{ icon: 'mastodon', label: 'Mastodon', href: 'https://m.webtoo.ls/@astro' },
],
}),
```

### `customCss`
Expand Down
14 changes: 9 additions & 5 deletions docs/src/content/docs/reference/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,19 +163,23 @@ Provide the root-level configuration keys you want to override.
To update nested configuration values, you must provide the entire nested object.

To extend an existing config option without overriding it, spread the existing value into your new value.
In the following example, a new [`social`](/reference/configuration/#social) media account is added to the existing configuration by spreading `config.social` into the new `social` object:
In the following example, a new [`social`](/reference/configuration/#social) media account is added to the existing configuration by spreading `config.social` into the new `social` array:

```ts {6-11}
```ts {6-15}
// plugin.ts
export default {
name: 'add-twitter-plugin',
hooks: {
'config:setup'({ config, updateConfig }) {
updateConfig({
social: {
social: [
...config.social,
twitter: 'https://twitter.com/astrodotbuild',
},
{
icon: 'twitter',
label: 'Twitter',
href: 'https://twitter.com/astrodotbuild',
},
],
});
},
},
Expand Down
4 changes: 1 addition & 3 deletions examples/basics/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ export default defineConfig({
integrations: [
starlight({
title: 'My Docs',
social: {
github: 'https://github.com/withastro/starlight',
},
social: [{ icon: 'github', label: 'GitHub', href: 'https://github.com/withastro/starlight' }],
sidebar: [
{
label: 'Guides',
Expand Down
4 changes: 1 addition & 3 deletions examples/markdoc/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ export default defineConfig({
markdoc(),
starlight({
title: 'My Docs',
social: {
github: 'https://github.com/withastro/starlight',
},
social: [{ icon: 'github', label: 'GitHub', href: 'https://github.com/withastro/starlight' }],
sidebar: [
{
label: 'Guides',
Expand Down
4 changes: 1 addition & 3 deletions examples/tailwind/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ export default defineConfig({
integrations: [
starlight({
title: 'Docs with Tailwind',
social: {
github: 'https://github.com/withastro/starlight',
},
social: [{ icon: 'github', label: 'GitHub', href: 'https://github.com/withastro/starlight' }],
sidebar: [
{
label: 'Guides',
Expand Down
3 changes: 1 addition & 2 deletions packages/starlight/__tests__/basics/config-errors.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,7 @@ test('errors with bad social icon config', () => {
"[AstroUserError]:
Invalid config passed to starlight integration
Hint:
**social.unknown**: Invalid enum value. Expected 'twitter' | 'mastodon' | 'github' | 'gitlab' | 'bitbucket' | 'discord' | 'gitter' | 'codeberg' | 'codePen' | 'youtube' | 'threads' | 'linkedin' | 'twitch' | 'azureDevOps' | 'microsoftTeams' | 'instagram' | 'stackOverflow' | 'x.com' | 'telegram' | 'rss' | 'facebook' | 'email' | 'reddit' | 'patreon' | 'signal' | 'slack' | 'matrix' | 'openCollective' | 'hackerOne' | 'blueSky' | 'discourse' | 'zulip' | 'pinterest' | 'tiktok' | 'nostr' | 'backstage' | 'farcaster' | 'confluence' | 'jira' | 'storybook' | 'npm' | 'sourcehut' | 'substack', received 'unknown'
**social.unknown**: Invalid url"
**social**: Expected type \`"array"\`, received \`"object"\`"
`
);
});
Expand Down
12 changes: 6 additions & 6 deletions packages/starlight/__tests__/basics/user-config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { StarlightConfigSchema } from '../../utils/user-config';
test('preserve social config order', () => {
const config = StarlightConfigSchema.parse({
title: 'Test',
social: {
twitch: 'https://www.twitch.tv/bholmesdev',
github: 'https://github.com/withastro/starlight',
discord: 'https://astro.build/chat',
},
social: [
{ icon: 'twitch', label: 'Twitch', href: 'https://www.twitch.tv/bholmesdev' },
{ icon: 'github', label: 'GitHub', href: 'https://github.com/withastro/starlight' },
{ icon: 'discord', label: 'Discord', href: 'https://astro.build/chat' },
],
});
expect(Object.keys(config.social || {})).toEqual(['twitch', 'github', 'discord']);
expect((config.social || []).map(({ icon }) => icon)).toEqual(['twitch', 'github', 'discord']);
});
5 changes: 3 additions & 2 deletions packages/starlight/components/Head.astro
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,13 @@ if (Astro.site) {
}

// Link to Twitter account if set in Starlight config.
if (config.social?.twitter) {
const twitterLink = config.social?.find(({ icon }) => icon === 'twitter' || icon === 'x.com');
if (twitterLink) {
headDefaults.push({
tag: 'meta',
attrs: {
name: 'twitter:site',
content: new URL(config.social.twitter.url).pathname,
content: new URL(twitterLink.href).pathname,
},
});
}
Copy link
Member Author

Choose a reason for hiding this comment

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

This change will overlap with #2927 but thankfully it’s small and easy to update for whichever PR merges second.

Expand Down
10 changes: 4 additions & 6 deletions packages/starlight/components/SocialIcons.astro
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,16 @@
import config from 'virtual:starlight/user-config';
import Icon from '../user-components/Icon.astro';

type Platform = keyof NonNullable<typeof config.social>;
type SocialConfig = NonNullable<NonNullable<typeof config.social>[Platform]>;
const links = Object.entries(config.social || {}) as [Platform, SocialConfig][];
const links = config.social || [];
---

{
links.length > 0 && (
<>
{links.map(([platform, { label, url }]) => (
<a href={url} rel="me" class="sl-flex">
{links.map(({ label, href, icon }) => (
<a {href} rel="me" class="sl-flex">
<span class="sr-only">{label}</span>
<Icon name={platform} />
<Icon name={icon} />
</a>
))}
</>
Expand Down
8 changes: 3 additions & 5 deletions packages/starlight/schemas/hero.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { z } from 'astro/zod';
import type { SchemaContext } from 'astro:content';
import { Icons, type StarlightIcon } from '../components/Icons';

const iconNames = Object.keys(Icons) as [StarlightIcon, ...StarlightIcon[]];
import { IconSchema } from './icon';

export const HeroSchema = ({ image }: SchemaContext) =>
z.object({
Expand Down Expand Up @@ -55,9 +53,9 @@ export const HeroSchema = ({ image }: SchemaContext) =>
* Can be an inline `<svg>` or the name of one of Starlight’s built-in icons.
*/
icon: z
.union([z.enum(iconNames), z.string().startsWith('<svg')])
.union([IconSchema(), z.string().startsWith('<svg')])
.transform((icon) => {
const parsedIcon = z.enum(iconNames).safeParse(icon);
const parsedIcon = IconSchema().safeParse(icon);
return parsedIcon.success
? ({ type: 'icon', name: parsedIcon.data } as const)
: ({ type: 'raw', html: icon } as const);
Expand Down
7 changes: 7 additions & 0 deletions packages/starlight/schemas/icon.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { z } from 'astro/zod';
import { Icons, type StarlightIcon } from '../components/Icons';

const iconNames = Object.keys(Icons) as [StarlightIcon, ...StarlightIcon[]];

/** String that matches the name of one of Starlight’s built-in icons. */
export const IconSchema = () => z.enum(iconNames);
Loading