Open antony opened 3 years ago
I think the problem is coming from using "Web components", which is a alternative technology to Svelte. In a real Svelte component, the problem does not appear, because there is no extends HTMLElement
and browser-related code can run in onMount
, which side-steps the issue.
I really don't understand why anyone should go for web components. They have been risen and fallen with polymer. Like no major web framework uses them. Simple bundled Modules are just way more hassle-free and work everywhere. Nonetheless, is there any way to get it working with svelte-kit? It's in beta for a while now and I think nobody will start a new project with plain svelte anymore. So it is a very relevant issue.
Web components have definitely had a bumpy ride and there are many negative things that can be said, but it's a standard none the less and it's where my focus is. There's been amazing improvements in browser support for enabling SSR with web components such as the new Declarative Shadow DOM API. There's also a bunch of other exciting proposals in the pipeline (eg: Constructable Stylesheets and HTML Modules).
Polymer has morphed into Lit and Google has recently released Lit 2 which has seen amazing adoption. Google has doubled down on it, and lot of major platforms/apps are shifting in this same direction. If I want to author a library that is framework agnostic and future proof then it can't be written at the framework layer (whatever the flavour of the month is or what you might think is the best). I'm also aware the Svelte can compile down to web components and I love the DX (huge Svelte fan)... but there are many issues with a compiled set of web components that we've experienced at work (this applies to Stencil as well).
I completely acknowledge that the integration packages were unfortunately not well written in Vime but I'm rectifying a lot of that on the new media player I'm working on which I'll announce soon. Framework support will hopefully come directly from Lit directly as they already support React.
I'm completely aware svelte-kit
is the future of Svelte and I'm definitely looking to add better support. Please keep in mind that this is worked on mostly in spare time outside of work/family/life. I don't have the bandwidth to address a lot of issues with Vime at this time. There are great things in the works, just a little patience and I'll get there.
Thanks!
But despite these errors / warnings during compilation, Vime works with Sapper when dynamically imported and used with <svelte:component>
, as far as I can tell. Or are there problems further down the line?
@silllli : Do you have a shortened code example of how you use <svelte:component>
? That might be helpful for us.
Sure:
<script>
import { onMount } from 'svelte';
let Player;
let Video;
onMount(async () => {
// NOTE: parentheses turn destructuring assignments into expressions
({ Player, Video } = await import('@vime/svelte'));
});
</script>
<svelte:component this={Player} controls>
<svelte:component this={Video} crossorigin="">
<source data-src="file.mp4">
</svelte:component>
</svelte:component>
The above code works great for me in dev mode, but running build gives a
HTMLElement is not defined ReferenceError: HTMLElement is not defined
Any ideas? I can provide a repro if needed.
Seems like my issue might be with Vite/SvelteKit eagerly bundling https://github.com/sveltejs/kit/issues/1570
Arguments to <svelte:component this={Player}>
don’t seem to get passed correctly (at least autoplay
doesn’t). 😢
While trying to embed a Vimeo video on Kit 115 I get the following error:
ReferenceError: HTMLElement is not defined
at /node_modules/@vime/core/dist/custom-elements/index.js?v=e741b189:826:14
at instantiateModule (D:\Github\conference\node_modules\vite\dist\node\chunks\dep-bc228bbb.js:68693:166)
I agree that supporting Kit more thoroughly would be a good move given the direction of the project.
Damn, really disappointed this fantastic lib doesn't work with SvelteKit. Just got the HTMLElement is not defined
error after following the Getting Started / Hls instructions in the docs.
EDIT: Actually, seems to work using the <svelte:component>
workaround..
EDIT: Here's my working code for anyone struggling:
<script>
import { onMount } from 'svelte';
let isMounted = false;
let video;
let Player;
let Hls;
onMount(async () => {
const vime = await import('@vime/svelte');
Player = vime.Player;
Hls = vime.Hls;
isMounted = true;
setTimeout(() => {
video.play();
}, 100);
})
</script>
{#if isMounted === true}
<svelte:component this={Player} bind:this={video} controls>
<svelte:component this={Hls} version="latest" config={hlsConfig} crossorigin="">
<source data-src="https://stream.mux.com/abc123.m3u8" type="application/x-mpegURL">
</svelte:component>
</svelte:component>
{/if}
SvelteKit: 1.0.0-next.116 Svelte: 3.38.3
EDIT: I'm experiencing issues calling methods on the Player using <svelte:component>
:
index.js?v=188b6dfd:2980 Uncaught (in promise) TypeError: fullscreen error
at Object.requestFullscreen (index.js?v=188b6dfd:2980)
at FullscreenController.makeEnterFullscreenRequest (index.js?v=188b6dfd:3078)
at FullscreenController.requestFullscreen (index.js?v=188b6dfd:3075)
at HTMLElement.enterFullscreen (index.js?v=188b6dfd:5233)
at proxy.enterFullscreen (Player.svelte? [sm]:93)
😞
EDIT: Hm, actually finding that I'm able to get it work without <svelte:component>
:
<script>
import { onMount } from 'svelte';
let isMounted = false;
let video;
let Player;
let Hls;
onMount(async () => {
const vime = await import('@vime/svelte');
Player = vime.Player;
Hls = vime.Hls;
isMounted = true;
setTimeout(() => {
video.play();
}, 100);
})
</script>
{#if isMounted === true}
<Player this={Player} bind:this={video} controls>
<Hls this={Hls} version="latest" config={hlsConfig} crossorigin="">
<source data-src="https://stream.mux.com/abc123.m3u8" type="application/x-mpegURL">
</Hls>
</Player>
{/if}
With this code I'm finding that video.play()
, video.enterFullscreen()
etc. are actually working. ..Although I can't set props on it:
Player.svelte? [sm]:125 Uncaught Error: <Player>: Props cannot be set directly on the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'
at Player.set currentTime [as currentTime] (Player.svelte? [sm]:125)
at proxy.set (proxy.js:110)
EDIT: Okay, so it actually works fine as a Web Component:
<script context="module">
let player = null;
export function pause() {
player.pause();
}
</script>
<script>
// deps
import { onMount } from 'svelte';
// stores
import { currentTimeSec, isPlaying } from '$lib/stores/media.js';
$: if ($isPlaying) {
if (player !== null) {
player.play()
}
} else {
if (player !== null) {
player.pause()
}
}
function handleTimeUpdate(event) {
currentTimeSec.set(event.detail)
}
function movePlayheadToTime(time) {
player.currentTime = time;
if (!$isPlaying) {
currentTimeSec.set(time)
}
}
function setPlaybackRate(playbackRate) {
player.playbackRate = playbackRate;
}
let hlsConfig = {};
onMount(async () => {
player = document.querySelector('vm-player');
})
</script>
<div id="container">
<vm-player playsinline on:vmCurrentTimeChange={handleTimeUpdate}>
<vm-hls
cross-origin="true"
poster="https://image.mux.com/muxid-123/thumbnail.png?width=214&height=121&fit_mode=pad">
<source data-src="https://stream.mux.com/muxid-123.m3u8" type="application/x-mpegURL" />
</vm-hls>
<vm-default-ui></vm-default-ui>
</vm-player>
</div>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="/favicon.ico" />
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@vime/core@^5/themes/default.css"
/>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@vime/core@^5/themes/light.css"
/>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script
defer
type="module"
src="https://cdn.jsdelivr.net/npm/@vime/core@^5/dist/vime/vime.esm.js"
>
</script>
%svelte.head%
</head>
<body class="text-gray-300">
<div id="svelte">%svelte.body%</div>
</body>
</html>
Which is the official recommended way to implement Vime on a SvelteKit project? Can we rise a feature request for SvelteKit support? At least add some kind of mention of SvelteKit on the documentation.
We have it working in SvelteKit by using the web component version and just loading the script.
why are the docs trash for svelte? can someone post an official solution here?
why are the docs trash for svelte? can someone post an official solution here?
The docs are for Svelte. Svelte Kit renders on the server, so it won't work the same. This is an open source project that I'm sure is a ton of work to maintain. No need to be rude. As I stated in my previous comment, that was trying to be helpful, if you use the web components version, it works without issue. I'm sure the maintainers would love a PR if you have time to update the docs.
Here's how I've got Vime working with SvelteKit using @vime/core
<script>
import { onMount } from 'svelte';
export let src;
let showPlayer = false;
let player;
onMount(async () => {
const { defineCustomElements } = await import('@vime/core');
defineCustomElements();
showPlayer = true;
});
</script>
{#if showPlayer}
<vm-player bind:this={player}>
<vm-video>
<source data-src={src} type="video/mp4" />
</vm-video>
<vm-ui>
<vm-default-controls />
</vm-ui>
</vm-player>
{/if}
@sveltejs/kit@1.0.0-next.180 @vime/core@5.0.33 svelte@3.43.1
Did someone get it working on sveltekit with the svelte bindings (@vime/svelte)?
Hi @mihar-22, will Vidstack be available as an importable component in Svelte?
Hey @benwoodward! We're going to start out with recommending web components for Svelte to reduce the initial workload and maintenance burden (espescially when it comes to documentation). Based on feedback we can definitely consider exporting all elements as Svelte components.
Here's how I've got Vime working with SvelteKit using
@vime/core
<script> import { onMount } from 'svelte'; export let src; let showPlayer = false; let player; onMount(async () => { const { defineCustomElements } = await import('@vime/core'); defineCustomElements(); showPlayer = true; }); </script> {#if showPlayer} <vm-player bind:this={player}> <vm-video> <source data-src={src} type="video/mp4" /> </vm-video> <vm-ui> <vm-default-controls /> </vm-ui> </vm-player> {/if}
@sveltejs/kit@1.0.0-next.180 @vime/core@5.0.33 svelte@3.43.1
Thanks this really help solve my issue. Vime player does not work in .svelte if you do an import.
<script> import { onMount } from 'svelte'; export let src; let showPlayer = false; let player; onMount(async () => { const { defineCustomElements } = await import('@vime/core'); defineCustomElements(); showPlayer = true; }); </script> {#if showPlayer} <vm-player bind:this={player}> <vm-video> <source data-src={src} type="video/mp4" /> </vm-video> <vm-ui> <vm-default-controls /> </vm-ui> </vm-player> {/if}
does it mean i can't use this code inside a .svelte
file?
where else would you use it?
<script> import { onMount } from 'svelte'; export let src; let showPlayer = false; let player; onMount(async () => { const { defineCustomElements } = await import('@vime/core'); defineCustomElements(); showPlayer = true; }); </script> {#if showPlayer} <vm-player bind:this={player}> <vm-video> <source data-src={src} type="video/mp4" /> </vm-video> <vm-ui> <vm-default-controls /> </vm-ui> </vm-player> {/if}
does it mean i can't use this code inside a
.svelte
file? where else would you use it?
You should be able to use it in a .svelte file
@louishuddleston
You should be able to use it in a .svelte file
is there a way to change the width/height of the player?
Sure:
<script> import { onMount } from 'svelte'; let Player; let Video; onMount(async () => { // NOTE: parentheses turn destructuring assignments into expressions ({ Player, Video } = await import('@vime/svelte')); }); </script> <svelte:component this={Player} controls> <svelte:component this={Video} crossorigin=""> <source data-src="file.mp4"> </svelte:component> </svelte:component>
This worked wonderfully for me, thank you!
<script lang="ts">
import { onMount } from 'svelte';
export let videoId: number | null = 0;
let Player: any = null;
let Vimeo: any = null;
onMount(async () => {
// NOTE: parentheses turn destructuring assignments into expressions
({ Player, Vimeo } = await import('@vime/svelte'));
});
// set to 0 in case it's null and let the vimeo player handle cases where there's no video
$: videoId = videoId || 0;
</script>
<svelte:component this={Player} controls>
<svelte:component this={Vimeo} videoId={videoId} />
</svelte:component>
Documentation
SSR Examples for new Vime JS.
Documentation page URL: Does not yet exist
Reason: The only existing "documentation" around this is the final comment on https://github.com/vime-js/vime/issues/38 - using dynamic imports is easy, but then you have to also use
svelte:component
in order to use those dynamic modules, and even then there are loads of console errors during build:It would be good to have a written example of using the new "web components" based VimeJS, as I can't see a clear path forward for using it in an SSR enabled environment.