├── 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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | ![npm](https://img.shields.io/npm/v/astro-social-share) 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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | 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 | -------------------------------------------------------------------------------- /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 | 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 | -------------------------------------------------------------------------------- /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 | [![Built with Starlight](https://astro.badg.es/v2/built-with-starlight/tiny.svg)](https://starlight.astro.build) 4 | 5 | ``` 6 | npm create astro@latest -- --template starlight 7 | ``` 8 | 9 | [![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/starlight/tree/main/examples/basics) 10 | [![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/starlight/tree/main/examples/basics) 11 | [![Deploy with Vercel](https://vercel.com/button)](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 | }); --------------------------------------------------------------------------------