SvelteKit Embed
This is a collection of embed components I use on a regular basis packaged up for use.
Each component (except Tweet
, Toot
and Zencastr
) is wrapped in
an intersection observer GeneralObserver
which will load up the
component when it scrolls into the viewport.
Currently the GeneralObserver is enabled so all the components are loaded on page load.
You can toggle the GeneralObserver on and off from here, just bear in mind that if this is the first time you’ve loaded this page then the default is to load all the components.
If you want to see the intersection observer in action then you’ll need to toggle it off, reload the page and scroll down the page.
All props listed are the defaults for the component.
Install it
pnpm i -D sveltekit-embed # npm or yarn even
Use it
<!-- +page.svelte -->
<script>
import { AnchorFm } from 'sveltekit-embed';
</script>
<AnchorFm
episodeUrl="purrfect-dev/embed/episodes/3-6---Effective-Testing-using-Cypress-io-e1vbg9m"
/>
Available Components List
Your embed not here? Start a discussion or open a PR.
- AnchorFm
- Bluesky
- Buzzsprout
- CodePen
- Deezer
- GenericEmbed
- Gist
- Guild
- Relive
- SimpleCast
- Slides
- SoundCloud
- Spotify
- StackBlitz
- TikTok
- Toot
- Tweet
- Vimeo
- YouTube
- Zencastr
AnchorFm
Props:
episodeUrl: string;
height: string = '100px';
width: string = '100%';
disable_observer: boolean = false;
Usage:
<AnchorFm
episodeUrl="purrfect-dev/embed/episodes/3-6---Effective-Testing-using-Cypress-io-e1vbg9m"
/>
Output:
Bluesky
Get the did:plc
identifier from the embed post option on Bluesky.
Props:
post_id = '',
width = '100%',
iframe_styles = '',
Usage:
<Bluesky
disable_observer="{$disable_observer_store}"
post_id="did:plc:nlvjelw3dy3pddq7qoglleko/app.bsky.feed.post/3l6ud34tnwn2k"
iframe_styles="border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);"
/>
Output:
Buzzsprout
Props:
buzzsproutId: string;
width: string = '100%';
height: string = '200px';
disable_observer: boolean = false;
Usage:
<Buzzsprout
buzzsproutId="190346/9866589-185-scott-spence-from-vba-analyst-to-webdev"
/>
Output:
CodePen
Props:
height: string = '500px'
width: string = '100%'
codePenId: string = ''
tabs:
| string[]
| 'js'
| 'css'
| 'scss'
| 'less'
| 'result' = 'result'
clickToLoad: boolean = true
editable: boolean = true
theme: string | 'light' | 'dark' | 'default' = 'default'
disable_observer: boolean = false
iframe_styles: string = `
height: ${height};
width: ${width};
`
Usage:
For a CodePen URL like this: https://codepen.io/spences10/pen/WNMvXpa take the codePenId
this WNMvXpa
and add it to the component.
<CodePen codePenId="WNMvXpa" />
Output:
Deezer
Props:
theme: string = 'auto';
frameSrc: string = '';
height: string = '300px';
width: string = '100%';
disable_observer: boolean = false;
iframe_styles: string = `
border-radius: 0.6rem;
height: ${height};
width: ${width};
`;
Usage:
<Deezer frameSrc="show/496882" />
Output:
GenericEmbed
This component passes all provided props to the iframe This component also provides a slot, to bring your own markup besides the iframe
Props:
src: string = '';
title: string = '';
height: string = '152px';
width: string = '100%';
disable_observer: boolean = false;
Usage:
<GenericEmbed
width="100%"
height="152px"
data-testid="spotify"
title="spotify-generic"
src={`https://open.spotify.com/embed/show/4XPl3uEEL9hvqMkoZrzbx5`}
frameBorder="0"
allow="encrypted-media"
style="border-radius: 0.9rem;"
/>
Output:
Gist
Props:
width = '100%';
height = '320px';
gistUri = '';
disable_observer: boolean = false;
iframe_styles: string = `
height: ${height};
width: ${width};
`;
Usage:
<Gist gistUri="Ennoriel/8c89dc3615292f0a40b04f4f876afd77" />
Output:
Guild
Props:
height: string = '380px'
width: string = '100%'
card_id: string
type: 'guild' | 'user' | 'event' | 'presentation' =
'guild'
display_type:
| 'card'
| 'item'
| 'events/latest'
| 'events/upcoming'
| 'events/past'
| 'presentations/latest'
| 'presentations/upcoming'
| 'presentations/other' = 'card'
disable_observer: boolean = false
Usage:
<Guild
type="guild"
card_id="svelte-society-london"
display_type="events/latest"
/>
Output:
Relive
Props:
reliveId: string = '';
width: string = '100%';
disable_observer: boolean = false;
Usage:
<Relive reliveId="vAOZokmYVo6" />
Output:
SimpleCast
Props:
episodeId: string = '';
theme: string = `dark`;
disable_observer: boolean = false;
Usage:
<SimpleCast episodeId="1c254f66-5d75-48ef-b960-4cfec94baa0b" />
Output:
Slides
Props:
width: string = '100%'
height: string = '420px'
username: string = ''
title: string = ''
byline: 'hidden' | 'visible' | 'default' = 'hidden'
share: 'hidden' | 'visible' | 'default' = 'hidden'
style:
| 'light'
| 'dark'
| 'hidden'
| 'transparent'
| 'default' = 'dark'
disable_observer: boolean = false
Usage:
<Slides
username="spences10"
title="building-with-sveltekit-and-graphql"
/>
Output:
SoundCloud
Props:
soundcloudLink: string = '';
width: string = '100%';
height: string = '300px';
showVisual: boolean = true;
disable_observer: boolean = false;
iframe_styles: string = '';
Usage:
<SoundCloud
soundcloudLink="https://soundcloud.com/dimension_uk/sets/prospa-want-need-love"
/>
Output:
Spotify
Props:
spotifyLink: string = '';
height: string = '100%';
width: string = '152px';
disable_observer: boolean = false;
iframe_styles: string = `
border-radius: 0.8rem;
height: ${height};
width: ${width};
`;
Usage:
<Spotify spotifyLink="show/4XPl3uEEL9hvqMkoZrzbx5" />
Output:
StackBlitz
Props:
width: string = '100%'
height: string = '500px'
id: string = ''
view: 'editor' | 'preview' | 'default' = 'default'
clickToLoad: boolean = true //ctl
hideNavigation: boolean = false //hideNavigation
hideExplorer: boolean = true
theme: string | 'light' | 'dark' | 'default' = 'dark'
file: string | undefined
disable_observer: boolean = false
iframe_styles: string = `
height: ${height};
width: ${width};
Usage:
<StackBlitz id="vitejs-vite-yyoood" theme="light" />
Output:
TikTok
Props:
tiktokId: string;
width?: string = '100%';
height?: string = '600px';
controls?: boolean = true;
progress_bar?: boolean = true;
play_button?: boolean = true;
volume_control?: boolean = true;
fullscreen_button?: boolean = true;
timestamp?: boolean = true;
loop?: boolean = false;
autoplay?: boolean = false;
music_info?: boolean = false;
description?: boolean = false;
rel?: boolean = true;
native_context_menu?: boolean = true;
closed_caption?: boolean = true;
disable_observer?: boolean = false;
Usage:
<TikTok
tiktokId="6718335390845095173"
width="100%"
height="600px"
autoplay="{false}"
loop="{true}"
music_info="{true}"
description="{true}"
/>
Output:
Toot
Props:
instance: string = '';
username: string = '';
tootId: string = '';
Usage:
<Toot
instance="mas.to"
username="@spences10"
tootId="109252587760962553"
/>
Output:
Tweet
Props:
tweetLink: string = '';
theme: string = 'dark' | 'light' = 'light';
Usage:
<Tweet
tweetLink="adamwathan/status/959078631434731521"
theme="dark"
/>
Output:
Vimeo
Props:
vimeoId: string = ''
autoPlay: boolean = false
aspectRatio: string = '16:9'
skipTo: { h: 0, m: 0, s: 0 }
disable_observer: boolean = false
Usage:
<Vimeo vimeoId="246846978" />
Output:
YouTube
Props:
youTubeId: string = ''
listId: string = ''
autoPlay: boolean = false
aspectRatio: string = '16:9'
skipTo: { h: 0, m: 0, s: 0 }
disable_observer: boolean = false
export let iframe_styles: string = `
border-radius: 0.6rem;
`
Usage:
<YouTube youTubeId="L7_z8rcbFPg" />
Output:
Zencastr
Props:
zencastrId: string = '';
Usage:
<Zencastr zencastrId="TARGseQu" />
Output:
View on Zencastr