SmartVideo runs in any web app, including single-page apps built with Angular, React, or Vue. The main things to know are which embed form to use inside a framework, where to load the snippet, and a few gotchas around re-rendering, server-side rendering, and iOS.
Use the <div class="smartvideo"> form
Both embed forms work, but in a framework the <div class="smartvideo"> form is usually the cleaner choice because it sidesteps the way frameworks treat unknown custom elements:
- Angular rejects an unknown
<smartvideo>element at compile time unless you addCUSTOM_ELEMENTS_SCHEMAto your module (or to a standalone component’sschemas). The<div class="smartvideo">form is a plain element, so it needs no schema change. - React renders the div fine, but in JSX you must write
className, notclass. React drops aclassattribute on a<div>(it warns in the console), so the player never sees thesmartvideoclass and the video won’t load. UseclassName="smartvideo". - Vue tries to resolve
<smartvideo>as a component - in Vue 3 mark it as a custom element via the compiler’sisCustomElementoption (set in your Vite or vue-cli config); in Vue 2 useVue.config.ignoredElements = ['smartvideo']. Thedivform needs neither.
Drop the video in wherever you want it to appear, using the same attributes you’d put on the tag. In an HTML template (Angular, Vue):
<div class="smartvideo swarm-fluid"
src="https://your-video.example.com/file.mp4"
width="1280" height="720" controls>
</div>
In React (JSX), the same thing with className:
<div className="smartvideo swarm-fluid"
src="https://your-video.example.com/file.mp4"
width={1280} height={720} controls>
</div>
Our player scans for both the <smartvideo> tag and the smartvideo class and treats them identically, so you lose nothing by using the div. The attributes match the tag - see Basic SmartVideo tag options. The src has to be a publicly reachable URL Swarmify can fetch and process - not localhost, and not an auth-gated or expiring signed URL.
Load the snippet once, in your root HTML
Add your SmartVideo snippet to the <head> of your app’s root HTML file (for example index.html in Angular CLI, Vite, or Create React App), not inside a component that mounts and unmounts. It only needs to load once for the whole app. You can grab the snippet from your dashboard; the non-WordPress setup guide walks through where it goes.
Server-rendered frameworks (Next.js, Nuxt, Angular Universal): there’s no static index.html, and the page first renders on the server where there’s no document. Load the snippet through the framework’s head mechanism (Next.js next/script, Nuxt useHead / app.head), and render the video container client-side only - next/dynamic with { ssr: false }, Nuxt <ClientOnly>, or an isPlatformBrowser guard in Angular - so the player’s DOM changes don’t collide with hydration.
If your app sends a Content-Security-Policy, allow the Swarmify script host in script-src (with a nonce or hash for the inline snippet) and the CDN in connect-src, media-src, and worker-src.
Videos that appear after navigation
In a single-page app, most video elements are added to the page after the first load - when a route changes or a component renders. SmartVideo watches the page for new videos and initializes them automatically as they appear, so you don’t normally re-initialize anything after navigation.
One thing to keep in mind: when SmartVideo initializes an element it replaces it with a <video> player and removes the smartvideo class, so your framework no longer “owns” that node. Put the embed in a container your framework renders once and then leaves alone - an empty wrapper you populate via a ref in React, a v-once container in Vue, or a host element kept out of change detection in Angular. If the component holding the video re-renders or unmounts on a route change, letting the framework reconcile the swapped node can throw DOM errors or spawn a duplicate player.
A note on mobile apps
SmartVideo is a browser-based player. If your mobile app is a web or hybrid app - for example one built with Ionic or Capacitor, which run your web app inside a web view - the same embed works. Two iOS notes: test on a real device rather than browser device-emulation (emulated iOS can falsely report video support - see Why is SmartVideo not working in an emulated iOS browser), and for inline, non-fullscreen playback make sure your native shell allows inline media playback, which Capacitor and Ionic can configure. If your app has fully native screens (Swift or Kotlin) that don’t use a web view, those screens can’t run the browser embed; play from your original video source there instead.
See also
- How to add a video to your non-WordPress website
- Using SmartVideo with Shopify, Squarespace, Wix, and other platforms
- Get started with SmartVideo
If you hit a snag wiring SmartVideo into your framework, email support@swarmify.com and we’ll help.
Keywords: Angular, React, Vue, Next.js, Nuxt, JavaScript framework, single-page app, SPA, server-side rendering, hydration, CUSTOM_ELEMENTS_SCHEMA, className, custom element, div class smartvideo, dynamic, route change, CSP, Ionic, Capacitor, web view, native app