{"id":21637782,"url":"https://github.com/oetherington/bluesky-embed-react","last_synced_at":"2025-05-07T11:06:07.959Z","repository":{"id":264500434,"uuid":"893435087","full_name":"oetherington/bluesky-embed-react","owner":"oetherington","description":"React component to embed bluesky posts, profiles and feeds","archived":false,"fork":false,"pushed_at":"2025-01-13T05:40:00.000Z","size":1627,"stargazers_count":1,"open_issues_count":10,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-17T06:04:30.834Z","etag":null,"topics":["at-protocol","atproto","atprotocol","bluesky","bluesky-client","component","embed","react","reactjs","widgets"],"latest_commit_sha":null,"homepage":"https://etherington.xyz/bluesky-embed-react","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oetherington.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-11-24T12:51:47.000Z","updated_at":"2024-12-15T14:33:53.000Z","dependencies_parsed_at":"2024-11-24T19:19:18.313Z","dependency_job_id":"973c5485-5ae6-4b82-a55e-a247dbab666c","html_url":"https://github.com/oetherington/bluesky-embed-react","commit_stats":null,"previous_names":["oetherington/bluesky-embed-react"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oetherington%2Fbluesky-embed-react","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oetherington%2Fbluesky-embed-react/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oetherington%2Fbluesky-embed-react/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oetherington%2Fbluesky-embed-react/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oetherington","download_url":"https://codeload.github.com/oetherington/bluesky-embed-react/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235524161,"owners_count":19003817,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["at-protocol","atproto","atprotocol","bluesky","bluesky-client","component","embed","react","reactjs","widgets"],"created_at":"2024-11-25T04:05:17.149Z","updated_at":"2025-01-25T01:07:37.488Z","avatar_url":"https://github.com/oetherington.png","language":"TypeScript","readme":"# Bluesky Embed React\n\n[![npm](https://img.shields.io/npm/v/bluesky-embed-react)](https://www.npmjs.com/package/bluesky-embed-react) [![Storybook](https://cdn.jsdelivr.net/gh/storybooks/brand@master/badge/badge-storybook.svg)](https://etherington.xyz/bluesky-embed-react) ![CI](https://github.com/oetherington/bluesky-embed-react/actions/workflows/ci.yml/badge.svg) [![Coverage](https://coveralls.io/repos/github/oetherington/bluesky-embed-react/badge.svg?branch=main)](https://coveralls.io/github/oetherington/bluesky-embed-react?branch=main) [![License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](https://raw.githubusercontent.com/oetherington/bluesky-embed-react/refs/heads/main/COPYING)\n\nLightweight configurable React component for embedding posts, profiles and feeds\nfrom [Bluesky](https://bsky.app).\n\nBluesky Embed React is an independent project, not affiliated with Bluesky.\n\n## Demo and Examples\n\nhttps://etherington.xyz/bluesky-embed-react\n\n![Light mode embed](./public/light-mode.png?raw=true)\n\n![Dark mode embed](./public/dark-mode.png?raw=true)\n\n## Install\n\n```bash\nnpm install bluesky-embed-react\n```\n\nor\n\n```bash\nyarn add bluesky-embed-react\n```\n\n## Basic Usage\n\n### Importing\n\n```jsx\nimport {\n\tBlueskyPost,\n\tBlueskyProfilePosts,\n\tBlueskyConfigProvider,\n} from \"bluesky-embed-react\";\n```\n\n### Embed a post\n\n```jsx\n\u003cBlueskyPost userHandle=\"bsky.app\" postId=\"3l6oveex3ii2l\" /\u003e\n```\n\n-   **userHandle** The username or DID of the user who created the post\n-   **postId** The ID of the post to embed\n\nFor instance, in the post https://bsky.app/profile/bsky.app/post/3l3t5pvpm222b\nthe `userHandle` is \"bsky.app\" and the `postId` is \"3l3t5pvpm222b\".\n\n### Embed a users profile feed\n\n```jsx\n\u003cBlueskyProfilePosts userHandle=\"bsky.app\" /\u003e\n```\n\n-   **userHandle** The username or DID of the user to embed\n-   **pageSize** The number of posts to display (and fetch if using infinite loading)\n-   **infiniteLoad** Enable inifite loading when scrolling to the end of the list\n\n## Configuration\n\nAdvanced configuration can be done by wrapping the components in a\n`BlueskyConfigProvider`:\n\n```jsx\n\u003cBlueskyConfigProvider hideAvatars\u003e\n\t\u003cBlueskyPost userHandle=\"bsky.app\" postId=\"3l6oveex3ii2l\" /\u003e\n\u003c/BlueskyConfigProvider\u003e\n```\n\nThe props are of type `BlueskyConfig` which has the following properties:\n\n-   **app** The base URL to use for outward links (default `https://bsky.app`)\n-   **service** The base URL for the API (default `https://public.api.bsky.app`)\n-   **openLinksInNewTab** Open links in place or in a new tab (default `false`)\n-   **avatarSize** The size of user avatars in pixels (default `42`)\n-   **hideAvatars** Whether or not to hide user avatars (default `false`)\n-   **hideEmbeds** Whether or not to hide embedded media and links (default `false`)\n-   **textPrimaryColor** CSS color string for primary text (default `light-dark(#0b0f14, #f1f3f5)`)\n-   **textSecondaryColor** CSS color string for secondary text (default `light-dark(#42576c, #aebbc9)`)\n-   **anchorColor** CSS color string for links (default `light-dark(#1083fe, #208bfe)`)\n-   **backgroundColor** CSS color string for post backgrounds (default `light-dark(#fff, #161e27)`)\n-   **borderColor** CSS color string for borders (default `light-dark(#d4dbe2, #2e4052)`)\n-   **loadingShimmer** CSS color string for the loading shimmer effect (default `linear-gradient(100deg, light-dark(#d5d5d5, #aaa) 40%, light-dark(#dbdbdb, #bdbdbd) 50%, light-dark(#d5d5d5, #aaa) 60%)`)\n-   **fontFamily** CSS font stack to apply to all posts (default `InterVariable, Inter, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\"`)\n-   **fontSize** CSS font size for main text (default `15px`)\n-   **embedFontSize** CSS font size for embedded media descriptions (default `14px`)\n-   **fontWeight** CSS font weight for main text (default `400`)\n-   **titleFontWeight** CSS font weight for title text (default `600`)\n-   **lineHeight** CSS line height for all text (default `140%`)\n-   **grid** Grid size in pixels used for calculating all margins and padding (default `8px`)\n-   **borderRadius** CSS border radius applied to posts and loaders (default `6px`)\n-   **width** CSS width applied to posts (default `600px`)\n-   **formatShortDate** Function to format dates into a short format\n-   **formatLongDate** Function to format dates into a long format\n\n### Switching between light mode and dark mode\n\nThe default colors use the CSS `light-dark` [color function](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/light-dark)\nto automatically switch colors based on the current operating system setting.\n\nTo enable this behaviour you need to set the CSS `color-scheme` property to\n`light dark`:\n\n```css\n:root {\n\tcolor-scheme: light dark;\n}\n```\n\nYou can also override the operating system to choose one theme or the other by\nsetting `color-scheme` to either `light` or `dark`. If you don't set `color-scheme`\nthen the browser will default to the light theme, even if the user has set\ntheir operating system to dark mode.\n\nFor more fine grained theme control you can set the color options manually\nin a `BlueskyConfig` provider (see above).\n\n## SSR\n\nYou can use the raw API to fetch data during SSR. For instance, in NextJS:\n\n```jsx\nimport {\n\tBlueskyPostsList,\n\tgetBlueskyClient,\n\tgetBlueskyProfilePosts,\n} from \"bluesky-embed-react\";\n\nexport default function Page({ profile, posts }) {\n\treturn \u003cBlueskyPostsList profile={profile} posts={posts} /\u003e;\n}\n\nexport const getStaticProps = async () =\u003e {\n\tconst client = getBlueskyClient();\n\tconst [profile, posts] = await Promise.all([\n\t\tgetBlueskyProfile(client, \"bsky.app\"),\n\t\tgetBlueskyProfilePosts(client, \"bsky.app\"),\n\t]);\n\treturn {\n\t\tprops: {\n\t\t\tprofile,\n\t\t\tposts,\n\t\t},\n\t};\n};\n```\n\n## License\n\nMIT © [oetherington](https://github.com/oetherington). See the included [COPYING](https://raw.githubusercontent.com/oetherington/bluesky-embed-react/refs/heads/main/COPYING) file for details.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foetherington%2Fbluesky-embed-react","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foetherington%2Fbluesky-embed-react","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foetherington%2Fbluesky-embed-react/lists"}