├── tsconfig.json
├── docs
├── tsconfig.json
├── src
│ ├── env.d.ts
│ ├── assets
│ │ ├── logo.png
│ │ └── houston.webp
│ └── content
│ │ ├── docs
│ │ ├── configuration
│ │ │ ├── slots.mdx
│ │ │ └── properties.mdx
│ │ ├── start-here
│ │ │ ├── demo.mdx
│ │ │ ├── getting-started.mdx
│ │ │ └── advanced-usage.mdx
│ │ └── index.mdx
│ │ └── config.ts
├── .vscode
│ ├── extensions.json
│ └── launch.json
├── .gitignore
├── package.json
├── public
│ └── favicon.svg
├── astro.config.mjs
└── README.md
├── src
├── types.ts
├── HackerNews.astro
├── Twitter.astro
├── Email.astro
├── Facebook.astro
├── LinkedIn.astro
├── Medium.astro
├── Bluesky.astro
├── SocialShare.astro
├── Reddit.astro
├── Whatsapp.astro
└── Threads.astro
├── vitest.config.ts
├── .gitignore
├── index.ts
├── README.md
├── LICENSE
├── package.json
└── tests
├── share.test.ts
└── button.test.ts
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "astro/tsconfigs/strict"
3 | }
--------------------------------------------------------------------------------
/docs/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "astro/tsconfigs/strict"
3 | }
--------------------------------------------------------------------------------
/docs/src/env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
--------------------------------------------------------------------------------
/docs/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/silent1mezzo/astro-social-share/HEAD/docs/src/assets/logo.png
--------------------------------------------------------------------------------
/docs/src/assets/houston.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/silent1mezzo/astro-social-share/HEAD/docs/src/assets/houston.webp
--------------------------------------------------------------------------------
/docs/src/content/docs/configuration/slots.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Slots"
3 | description: "How to install Astro Social Share"
4 | ---
--------------------------------------------------------------------------------
/docs/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": ["astro-build.astro-vscode"],
3 | "unwantedRecommendations": []
4 | }
5 |
--------------------------------------------------------------------------------
/docs/src/content/docs/configuration/properties.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Properties"
3 | description: "How to install Astro Social Share"
4 | ---
--------------------------------------------------------------------------------
/src/types.ts:
--------------------------------------------------------------------------------
1 | export default interface Props {
2 | url?: string;
3 | title?: string;
4 | description?: string;
5 | via?: string;
6 | }
--------------------------------------------------------------------------------
/docs/src/content/config.ts:
--------------------------------------------------------------------------------
1 | import { defineCollection } from 'astro:content';
2 | import { docsSchema } from '@astrojs/starlight/schema';
3 |
4 | export const collections = {
5 | docs: defineCollection({ schema: docsSchema() }),
6 | };
7 |
--------------------------------------------------------------------------------
/docs/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0",
3 | "configurations": [
4 | {
5 | "command": "./node_modules/.bin/astro dev",
6 | "name": "Development server",
7 | "request": "launch",
8 | "type": "node-terminal"
9 | }
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/docs/.gitignore:
--------------------------------------------------------------------------------
1 | # build output
2 | dist/
3 | # generated types
4 | .astro/
5 |
6 | # dependencies
7 | node_modules/
8 |
9 | # logs
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 | pnpm-debug.log*
14 |
15 |
16 | # environment variables
17 | .env
18 | .env.production
19 |
20 | # macOS-specific files
21 | .DS_Store
22 |
--------------------------------------------------------------------------------
/vitest.config.ts:
--------------------------------------------------------------------------------
1 | ///
2 | import { getViteConfig } from 'astro/config';
3 | import svgr from "vite-plugin-svgr";
4 |
5 | export default getViteConfig({
6 | plugins: [svgr()],
7 | test: {
8 | /* for example, use global to avoid globals imports (describe, test, expect): */
9 | // globals: true,
10 | },
11 | });
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # dependencies
2 | node_modules/
3 | package-lock.json
4 |
5 | # logs
6 | npm-debug.log*
7 | yarn-debug.log*
8 | yarn-error.log*
9 | pnpm-debug.log*
10 |
11 |
12 | # environment variables
13 | .env
14 | .env.production
15 |
16 | # macOS-specific files
17 | .DS_Store
18 |
19 | # ignore .astro directory
20 | .astro
21 |
22 | # ignore Jampack cache files
23 | .jampack/
24 |
25 | # yarn
26 | .yarn/*
27 | !.yarn/patches
28 | !.yarn/plugins
29 | !.yarn/releases
30 | !.yarn/sdks
31 | !.yarn/versions
32 | .pnp.*
33 |
34 |
35 |
--------------------------------------------------------------------------------
/docs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "docs",
3 | "type": "module",
4 | "version": "0.0.1",
5 | "scripts": {
6 | "dev": "astro dev",
7 | "start": "astro dev",
8 | "build": "astro check && astro build",
9 | "preview": "astro preview",
10 | "astro": "astro"
11 | },
12 | "dependencies": {
13 | "@astrojs/check": "^0.8.1",
14 | "@astrojs/starlight": "^0.25.1",
15 | "astro": "^4.10.2",
16 | "astro-social-share": "^2.0.1",
17 | "sharp": "^0.32.5",
18 | "typescript": "^5.5.3"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/docs/src/content/docs/start-here/demo.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Demo"
3 | description: "How to use Astro Social Share"
4 | ---
5 |
6 | import { SocialShare } from "astro-social-share";
7 |
8 |
12 |
13 | ```astro
14 | ---
15 | # Code used
16 | import { SocialShare } from "astro-social-share";
17 | ---
18 |
19 |
23 | ```
24 |
25 | ## Astro Social Share in production
26 | * [https://mckerlie.com](https://mckerlie.com)
--------------------------------------------------------------------------------
/docs/public/favicon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/HackerNews.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import type ButtonProps from './types';
3 |
4 | type Props = ButtonProps;
5 |
6 | const { url=Astro.request.url, title } = Astro.props;
7 |
8 | let URL = `http://news.ycombinator.com/submitlink?u=${url}&t=${title}`
9 |
10 | ---
11 |
12 |
13 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/index.ts:
--------------------------------------------------------------------------------
1 | export { default as EmailShareButton } from './src/Email.astro';
2 | export { default as FacebookShareButton } from './src/Facebook.astro';
3 | export { default as HackerNewsShareButton } from './src/HackerNews.astro';
4 | export { default as LinkedInShareButton } from './src/LinkedIn.astro';
5 | export { default as RedditShareButton } from './src/Reddit.astro';
6 | export { default as ThreadsShareButton } from './src/Threads.astro';
7 | export { default as TwitterShareButton } from './src/Twitter.astro';
8 | export { default as WhatsAppShareButton } from './src/Whatsapp.astro';
9 | export { default as MediumShareButton } from './src/Medium.astro';
10 | export { default as SocialShare } from './src/SocialShare.astro';
11 | export { default as BlueskyShareButton } from './src/Bluesky.astro';
--------------------------------------------------------------------------------
/src/Twitter.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import type ButtonProps from './types';
3 |
4 | type Props = ButtonProps;
5 |
6 | const { url=Astro.request.url, description, via} = Astro.props;
7 |
8 | let URL = `https://x.com/intent/tweet?url=${url}`
9 |
10 | if (description) URL += `&text=${description}`
11 | if (via) URL += `&via=${via}`
12 |
13 | ---
14 |
15 |
16 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/Email.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import type ButtonProps from './types';
3 |
4 | type Props = ButtonProps;
5 |
6 | const { url=Astro.request.url, title, description} = Astro.props;
7 | let URL = `mailto:?subject=${title}&body=${description}%0A${url}`
8 |
9 | ---
10 |
11 |
12 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/Facebook.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import type ButtonProps from './types';
3 |
4 | type Props = ButtonProps;
5 |
6 | const { url=Astro.request.url} = Astro.props;
7 |
8 | let URL = `https://www.facebook.com/sharer/sharer.php?u=${url}`
9 |
10 | ---
11 |
12 |
13 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/docs/src/content/docs/start-here/getting-started.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Installation"
3 | description: "How to install Astro Social Share"
4 | ---
5 |
6 | import { Tabs, TabItem } from "@astrojs/starlight/components";
7 |
8 | ## Install
9 |
10 |
11 |
12 | ```bash
13 | # Using NPM
14 | npm install astro-social-share
15 | ```
16 |
17 |
18 |
19 | ```bash
20 | # Using PNPM
21 | pnpm add astro-social-share
22 | ```
23 |
24 |
25 |
26 | ```bash
27 | # Using Yarn
28 | yarn add astro-social-share
29 | ```
30 |
31 |
32 |
33 | ## Usage
34 |
35 | ```astro
36 | ---
37 | import { SocialShare } from "astro-social-share";
38 | ---
39 |
40 |
44 | ```
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Astro Social Share
2 |
3 | Social media share buttons for your Astro site
4 |
5 | 
6 |
7 | ## ⭐ Features
8 | * ✅ Zero dependencies
9 | * ✅ Fully customizable
10 | * ✅ Share buttons for:
11 | * Facebook
12 | * Hacker News
13 | * LinkedIn
14 | * Reddit
15 | * X
16 | * Threads
17 | * WhatsApp
18 | * Medium
19 | * Threads
20 | * Bluesky
21 | * ✅ Small size
22 | * ✅ Included icons from https://simpleicons.org/
23 |
24 | ## 📦 Installation
25 |
26 | ```bash
27 | # Using NPM
28 | npm install astro-social-share
29 |
30 | # Using Yarn
31 | yarn add astro-social-share
32 |
33 | # Using PNPM
34 | pnpm add astro-social-share
35 | ```
36 |
37 | ## 📖 Documentation
38 |
39 | Please visit the [documentation](https://astro-social-share.mckerlie.com) for advanced usage.
40 |
41 | ## ⚡ Usage
42 |
43 | ```astro
44 | ---
45 | import { SocialShare } from "astro-social-share";
46 | ---
47 |
48 |
52 | ```
53 |
--------------------------------------------------------------------------------
/src/LinkedIn.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import type ButtonProps from './types';
3 |
4 | type Props = ButtonProps;
5 |
6 | const { url=Astro.request.url} = Astro.props;
7 |
8 | let URL = `https://www.linkedin.com/sharing/share-offsite/?url=${url}`
9 |
10 | ---
11 |
12 |
13 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/docs/src/content/docs/index.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Astro Social Share Documentation
3 | description: Quickly add social share buttons to your Astro site
4 | template: splash
5 | hero:
6 | tagline: Zero-config social share buttons
7 | image:
8 | file: ../../assets/logo.png
9 | actions:
10 | - text: Example Guide
11 | link: /start-here/getting-started
12 | icon: right-arrow
13 | variant: primary
14 | - text: View on GitHub
15 | link: https://github.com/silent1mezzo/astro-social-share
16 | icon: external
17 | ---
18 |
19 | import { Card, CardGrid } from '@astrojs/starlight/components';
20 |
21 | ## Next steps
22 |
23 |
24 |
25 | Just install and use!
26 |
27 |
28 | Learn more in [the Docs](https://starlight.astro.build/).
29 |
30 |
31 | Its true! Here is the [proof](https://www.npmjs.com/package/astro-social-share?activeTab=dependencies).
32 |
33 |
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Adam McKerlie
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/docs/astro.config.mjs:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'astro/config';
2 | import starlight from '@astrojs/starlight';
3 |
4 | // https://astro.build/config
5 | export default defineConfig({
6 | integrations: [
7 | starlight({
8 | title: 'Astro Social Share',
9 | social: {
10 | github: 'https://github.com/silent1mezzo/astro-social-share',
11 | },
12 | sidebar: [
13 | {
14 | label: 'Start Here',
15 | items: [
16 | // Each item here is one entry in the navigation menu.
17 | { label: 'Installation', slug: 'start-here/getting-started' },
18 | { label: 'Advanced Usage', slug: 'start-here/advanced-usage' },
19 | { label: 'Demo', slug: 'start-here/demo' },
20 | ],
21 | },
22 | {
23 | label: 'Configuration',
24 | items: [
25 | // Each item here is one entry in the navigation menu.
26 | { label: 'Properties', slug: 'configuration/properties' },
27 | { label: 'Slots', slug: 'configuration/slots' },
28 | ],
29 | },
30 | {
31 | label: 'Reference',
32 | autogenerate: { directory: 'reference' },
33 | },
34 | ],
35 | }),
36 | ],
37 | });
38 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "astro-social-share",
3 | "description": "Social media share buttons for your Astro site",
4 | "version": "2.2.0",
5 | "type": "module",
6 | "homepage": "https://github.com/silent1mezzo/astro-social-share#readme",
7 | "exports": {
8 | ".": "./index.ts"
9 | },
10 | "files": [
11 | "src",
12 | "index.ts"
13 | ],
14 | "repository": {
15 | "type": "git",
16 | "url": "https://github.com/silent1mezzo/astro-social-share"
17 | },
18 | "bugs": "https://github.com/silent1mezzo/astro-social-share/issues",
19 | "keywords": [
20 | "astro-component",
21 | "astro",
22 | "withastro",
23 | "astro-integration",
24 | "social-media",
25 | "social-share",
26 | "share",
27 | "icons"
28 | ],
29 | "license": "MIT",
30 | "scripts": {
31 | "postpublish": "PACKAGE_VERSION=$(cat package.json | grep \\\"version\\\" | head -1 | awk -F: '{ print $2 }' | sed 's/[\",]//g' | tr -d '[[:space:]]') && git tag v$PACKAGE_VERSION && git push --tags",
32 | "test": "vitest"
33 | },
34 | "devDependencies": {
35 | "astro": "^4.11.3",
36 | "vite-plugin-svgr": "^4.3.0",
37 | "vitest": "^1.6.1"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/tests/share.test.ts:
--------------------------------------------------------------------------------
1 | import { experimental_AstroContainer as AstroContainer } from 'astro/container';
2 | import { expect, test } from 'vitest';
3 |
4 | import SocialShare from "../src/SocialShare.astro";
5 | import FacebookShareButton from "../src/Facebook.astro";
6 |
7 | test('Basic Share Bar', async () => {
8 | const container = await AstroContainer.create();
9 | const result = await container.renderToString(SocialShare, {
10 | props: {
11 | url: 'https://example.com',
12 | title: 'Example Subject',
13 | description: 'Example Description'
14 | }
15 | });
16 | expect(result).toContain('class="astro-social-share"');
17 |
18 | // Currently there's 10 buttons, splitting on this gives us 11 parts.
19 | expect(result.split('social-share-btn').length).toBe(11);
20 | });
21 |
22 | test('Custom Share Bar', async () => {
23 | const container = await AstroContainer.create();
24 | const result = await container.renderToString(SocialShare, {
25 | props: {
26 | buttons: [FacebookShareButton],
27 | url: 'https://example.com',
28 | title: 'Example Subject',
29 | description: 'Example Description'
30 | }
31 | });
32 | expect(result).toContain('class="astro-social-share"');
33 |
34 | // We only pass in a single button, so we should only have 2 parts.
35 | expect(result.split('social-share-btn').length).toBe(2);
36 | });
--------------------------------------------------------------------------------
/src/Medium.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import type ButtonProps from './types';
3 |
4 | type Props = ButtonProps;
5 |
6 | const { url = Astro.request.url, title } = Astro.props;
7 |
8 | let URL = `https://medium.com/new-story?url=${encodeURIComponent(url)}&title=${title}`
9 |
10 | ---
11 |
12 |
13 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/Bluesky.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import type ButtonProps from './types';
3 |
4 | type Props = ButtonProps;
5 |
6 | const { url=Astro.request.url, title } = Astro.props;
7 | let text = ''
8 |
9 | if (title) text = encodeURIComponent(title)
10 | if (url) text += ` ${encodeURIComponent(url)}`
11 |
12 | let URL = `https://bsky.app/intent/compose`
13 |
14 | if (text) URL += `?text=${text}`
15 |
16 | ---
17 |
18 |
19 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/SocialShare.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import BlueskyShareButton from "./Bluesky.astro";
3 | import EmailShareButton from "./Email.astro";
4 | import FacebookShareButton from "./Facebook.astro";
5 | import HackerNewsShareButton from "./HackerNews.astro";
6 | import LinkedInShareButton from "./LinkedIn.astro";
7 | import MediumShareButton from "./Medium.astro";
8 | import RedditShareButton from "./Reddit.astro";
9 | import ThreadsShareButton from './Threads.astro';
10 | import TwitterShareButton from './Twitter.astro';
11 | import WhatsAppShareButton from './Whatsapp.astro';
12 | import type ButtonProps from './types';
13 |
14 | interface Props extends ButtonProps {
15 | buttons?: Object[];
16 | }
17 |
18 | const DEFAULT_COMPONENTS = [TwitterShareButton, FacebookShareButton, HackerNewsShareButton, LinkedInShareButton, RedditShareButton, EmailShareButton, WhatsAppShareButton, MediumShareButton, ThreadsShareButton, BlueskyShareButton];
19 |
20 | const { buttons=DEFAULT_COMPONENTS, url=Astro.request.url, title, description, via} = Astro.props;
21 |
22 | ---
23 |
24 |
38 |
39 |
40 | {buttons.map((Button) => )}
41 |
42 |
--------------------------------------------------------------------------------
/src/Reddit.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import type ButtonProps from './types';
3 |
4 | type Props = ButtonProps;
5 |
6 | const { url=Astro.request.url, title } = Astro.props;
7 |
8 | const encoded_url = encodeURIComponent(url);
9 | let URL = `https://www.reddit.com/submit?url=${encoded_url}&title=${title}`
10 |
11 | ---
12 |
13 |
14 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/Whatsapp.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import type ButtonProps from "./types";
3 |
4 | type Props = ButtonProps;
5 | const { url=Astro.request.url, description, style} = Astro.props;
6 |
7 | let URL = `whatsapp://send?text=`;
8 |
9 | if (description) URL += `${description} `;
10 | URL += `${url}`;
11 | ---
12 |
13 |
20 |
21 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/src/Threads.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import type ButtonProps from './types';
3 |
4 | type Props = ButtonProps;
5 |
6 | const { url=Astro.request.url, description, via} = Astro.props;
7 |
8 | let URL = `https://threads.net/intent/post?url=${url}`
9 |
10 | if (description) URL += `&text=${description}`
11 |
12 | ---
13 |
14 |
15 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/docs/src/content/docs/start-here/advanced-usage.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Advanced Usage"
3 | description: "How to install Astro Social Share"
4 | ---
5 |
6 | Simple, include all links
7 |
8 | ```astro
9 | ---
10 | import { SocialShare } from "astro-social-share";
11 | ---
12 |
13 |
17 | ```
18 |
19 | If you'd like to customize the share bar you can import the individual buttons and pass them into the `` component.
20 |
21 | ```astro
22 | ---
23 | import {
24 | FacebookShareButton,
25 | HackerNewsShareButton,
26 | LinkedInShareButton,
27 | MediumShareButton,
28 | RedditShareButton,
29 | ThreadsShareButton,
30 | TwitterShareButton,
31 | WhatsAppShareButton,
32 | BlueskyShareButton,
33 | SocialShare
34 | } from "astro-social-share";
35 |
36 | const BUTTONS = [TwitterShareButton, FacebookShareButton, BlueskyShareButton]
37 | ---
38 |
39 |
44 | ```
45 |
46 | ## Using your own icons
47 |
48 | If you'd like to pass in your own icons you can do so through the individual components.
49 |
50 | ```astro
51 | ---
52 | import {
53 | FacebookShareButton,
54 | TwitterShareButton,
55 | BlueskyShareButton,
56 | } from "astro-social-share";
57 |
58 | ---
59 |
60 |
61 |
62 |
63 |
64 |
69 |
70 |
71 | ```
72 |
73 | ## Using your own CSS
74 |
75 | If you'd like to style the share bar and icons you can pass in a global `
97 |
98 | ```
99 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | # Starlight Starter Kit: Basics
2 |
3 | [](https://starlight.astro.build)
4 |
5 | ```
6 | npm create astro@latest -- --template starlight
7 | ```
8 |
9 | [](https://stackblitz.com/github/withastro/starlight/tree/main/examples/basics)
10 | [](https://codesandbox.io/p/sandbox/github/withastro/starlight/tree/main/examples/basics)
11 | [](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fwithastro%2Fstarlight%2Ftree%2Fmain%2Fexamples%2Fbasics&project-name=my-starlight-docs&repository-name=my-starlight-docs)
12 |
13 | > 🧑🚀 **Seasoned astronaut?** Delete this file. Have fun!
14 |
15 | ## 🚀 Project Structure
16 |
17 | Inside of your Astro + Starlight project, you'll see the following folders and files:
18 |
19 | ```
20 | .
21 | ├── public/
22 | ├── src/
23 | │ ├── assets/
24 | │ ├── content/
25 | │ │ ├── docs/
26 | │ │ └── config.ts
27 | │ └── env.d.ts
28 | ├── astro.config.mjs
29 | ├── package.json
30 | └── tsconfig.json
31 | ```
32 |
33 | Starlight looks for `.md` or `.mdx` files in the `src/content/docs/` directory. Each file is exposed as a route based on its file name.
34 |
35 | Images can be added to `src/assets/` and embedded in Markdown with a relative link.
36 |
37 | Static assets, like favicons, can be placed in the `public/` directory.
38 |
39 | ## 🧞 Commands
40 |
41 | All commands are run from the root of the project, from a terminal:
42 |
43 | | Command | Action |
44 | | :------------------------ | :----------------------------------------------- |
45 | | `npm install` | Installs dependencies |
46 | | `npm run dev` | Starts local dev server at `localhost:4321` |
47 | | `npm run build` | Build your production site to `./dist/` |
48 | | `npm run preview` | Preview your build locally, before deploying |
49 | | `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
50 | | `npm run astro -- --help` | Get help using the Astro CLI |
51 |
52 | ## 👀 Want to learn more?
53 |
54 | Check out [Starlight’s docs](https://starlight.astro.build/), read [the Astro documentation](https://docs.astro.build), or jump into the [Astro Discord server](https://astro.build/chat).
55 |
--------------------------------------------------------------------------------
/tests/button.test.ts:
--------------------------------------------------------------------------------
1 | import { experimental_AstroContainer as AstroContainer } from 'astro/container';
2 | import { expect, test } from 'vitest';
3 | import BlueskyShareButton from '../src/Bluesky.astro';
4 | import EmailShareButton from "../src/Email.astro";
5 | import FacebookShareButton from '../src/Facebook.astro';
6 | import HackerNewsShareButton from '../src/HackerNews.astro';
7 | import LinkedInShareButton from '../src/LinkedIn.astro';
8 | import ThreadsShareButton from '../src/Threads.astro';
9 | import TwitterShareButton from '../src/Twitter.astro';
10 | import WhatsAppShareButton from '../src/Whatsapp.astro';
11 |
12 | const BUTTONS = [
13 | {
14 | obj: EmailShareButton,
15 | props: {
16 | url: 'https://example.com',
17 | title: 'Example Subject',
18 | description: 'Example Description'
19 | },
20 | expected: 'mailto:?subject=Example Subject&body=Example Description%0Ahttps://example.com'
21 | },
22 | {
23 | obj: FacebookShareButton,
24 | props: {
25 | url: 'https://example.com',
26 | title: 'Example Subject',
27 | description: 'Example Description'
28 | },
29 | expected: 'href="https://www.facebook.com/sharer/sharer.php?u=https://example.com'
30 |
31 | },
32 | {
33 | obj: HackerNewsShareButton,
34 | props: {
35 | url: 'https://example.com',
36 | title: 'Example Subject',
37 | description: 'Example Description'
38 | },
39 | expected: 'href="http://news.ycombinator.com/submitlink?u=https://example.com&t=Example Subject"'
40 | },
41 | {
42 | obj: LinkedInShareButton,
43 | props: {
44 | url: 'https://example.com',
45 | title: 'Example Subject',
46 | description: 'Example Description'
47 | },
48 | expected: 'href="https://www.linkedin.com/sharing/share-offsite/?url=https://example.com"'
49 | },
50 | {
51 | obj: ThreadsShareButton,
52 | props: {
53 | url: 'https://example.com',
54 | title: 'Example Subject',
55 | description: 'Example Description'
56 | },
57 | expected: 'href="https://threads.net/intent/post?url=https://example.com&text=Example Description"'
58 | },
59 | {
60 | obj: TwitterShareButton,
61 | props: {
62 | url: 'https://example.com',
63 | title: 'Example Subject',
64 | description: 'Example Description'
65 | },
66 | expected: 'href="https://x.com/intent/tweet?url=https://example.com&text=Example Description"'
67 | },
68 | {
69 | obj: WhatsAppShareButton,
70 | props: {
71 | url: 'https://example.com',
72 | title: 'Example Subject',
73 | description: 'Example Description'
74 | },
75 | expected: 'href="whatsapp://send?text=Example%20Description%20https://example.com"'
76 | },
77 | {
78 | obj: BlueskyShareButton,
79 | props: {
80 | url: 'https://example.com',
81 | title: 'Example Subject',
82 | description: 'Example Description'
83 | },
84 | expected: 'href="https://bsky.app/intent/compose?text=Example%20Subject https%3A%2F%2Fexample.com"'
85 | }
86 | ]
87 |
88 | test('Basic Buttons', async () => {
89 | const container = await AstroContainer.create();
90 |
91 | for (const element of BUTTONS) {
92 | const result = await container.renderToString(element.obj, {
93 | props: element.props
94 | });
95 | expect(result).toContain('social-share-btn');
96 | expect(result).toContain(element.expected);
97 | };
98 | });
99 |
100 | test('Custom SVG Icons', async () => {
101 | const container = await AstroContainer.create();
102 |
103 | for (const element of BUTTONS) {
104 | const result = await container.renderToString(element.obj, {
105 | props: element.props,
106 | slots: {
107 | default: ''
108 | }
109 | });
110 | expect(result).toContain('M44,24c0,11.045-8.955,20-20,20S4,35.045,4,24S12.955,4,24,4S44,12.955,44,24z');
111 | };
112 | });
--------------------------------------------------------------------------------