Interactive 360° videos are increasingly popular for training, product demos, and immersive experiences. In this article, we will create a SharePoint Framework (SPFx) WebPart that uses A-Frame — a powerful WebXR framework — to embed 360° video playback directly inside modern SharePoint pages.


🎥 Building a 360° Video WebPart in SharePoint Online with A-Frame


🔹 Introduction

Interactive 360° videos are increasingly popular for training, product demos, and immersive experiences. In this article, we will create a SharePoint Framework (SPFx) WebPart that uses A-Frame — a powerful WebXR framework — to embed 360° video playback directly inside modern SharePoint pages.

Unlike specialized libraries such as Photo-Sphere-Viewer, A-Frame gives us the flexibility to render videos as:

  • Immersive spheres (full VR mode)
  • Flat cinema screens (like watching a movie)
  • Curved screens (IMAX-style experiences)

🔹 Prerequisites

  • SharePoint Online tenant with App Catalog enabled
  • Node.js LTS (16.x recommended for SPFx 1.17+)
  • Yeoman + SPFx generator
  • Visual Studio Code or another editor

🔹 Step 1 — Create the SPFx Project

yo @microsoft/sharepoint

  • WebPart name: Video360Viewer
  • Framework: React

🔹 Step 2 — Install A-Frame

npm install aframe

A-Frame will be bundled automatically into your SPFx package.


🔹 Step 3 — Create the React Component

📂 src/webparts/video360Viewer/components/Video360Viewer.tsx

import * as React from 'react';
import 'aframe';
import styles from './Video360.module.scss';

export interface IVideo360Props {
  videoUrl: string;
  cinemaMode?: boolean; // true = flat screen, false = full 360°
}

export default class Video360 extends React.Component<IVideo360Props> {
  public render(): React.ReactElement<{}> {
    const { videoUrl, cinemaMode } = this.props;

    return (
      <div className={styles.video360}>
        <a-scene embedded>
          <a-assets>
            <video
              id="video360"
              src={videoUrl}
              loop
              autoPlay
              crossOrigin="anonymous"
              playsInline
              muted
            ></video>
          </a-assets>

          {cinemaMode ? (
            // Cinema mode: flat screen
            <a-video
              src="#video360"
              width="16"
              height="9"
              position="0 2 -8"
            ></a-video>
          ) : (
            // Immersive mode: full 360° sphere
            <a-videosphere src="#video360"></a-videosphere>
          )}

          {/* Default camera */}
          <a-entity camera look-controls position="0 1.6 0"></a-entity>
        </a-scene>
      </div>
    );
  }
}


🔹 Step 4 — Connect to the WebPart

📂 src/webparts/video360Viewer/Video360ViewerWebPart.ts

import * as React from 'react';
import * as ReactDom from 'react-dom';
import {
  BaseClientSideWebPart,
  IPropertyPaneConfiguration,
  PropertyPaneTextField,
  PropertyPaneToggle
} from '@microsoft/sp-webpart-base';

import Video360, { IVideo360Props } from './components/Video360Viewer';

export interface IVideo360ViewerWebPartProps {
  videoUrl: string;
  cinemaMode: boolean;
}

export default class Video360ViewerWebPart
  extends BaseClientSideWebPart<IVideo360ViewerWebPartProps> {

  public render(): void {
    const element: React.ReactElement<IVideo360Props> = React.createElement(
      Video360,
      {
        videoUrl: this.properties.videoUrl,
        cinemaMode: this.properties.cinemaMode
      }
    );

    ReactDom.render(element, this.domElement);
  }

  protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
    return {
      pages: [
        {
          header: { description: '360° Video Settings' },
          groups: [
            {
              groupName: 'Options',
              groupFields: [
                PropertyPaneTextField('videoUrl', {
                  label: 'Video URL (SharePoint or external)',
                  description: 'Example: https://cdn.bitmovin.com/content/assets/playhouse-vr/progressive.mp4'
                }),
                PropertyPaneToggle('cinemaMode', {
                  label: 'Cinema mode (flat screen)',
                  onText: 'On',
                  offText: 'Off'
                })
              ]
            }
          ]
        }
      ]
    };
  }
}


🔹 Step 5 — Test in the Workbench

Run the local workbench:

gulp serve

For authenticated SharePoint videos, deploy to the online workbench:

https://<tenant>.sharepoint.com/sites/dev/_layouts/15/workbench.aspx


🔹 Modes of Playback

🎬 Cinema Mode (Flat Screen)

  • Video is projected on a 16:9 rectangle in front of the user.
  • Best for standard videos or when you want a “movie theater” feel.
<a-video src="#video360" width="16" height="9" position="0 2 -8"></a-video>


🌐 Immersive Mode (360° Sphere)

  • Video is wrapped around the user in a sphere.
  • Best for true equirectangular 360° videos.
<a-videosphere src="#video360"></a-videosphere>


🌀 Curved Cinema (Optional)

You can also project onto a curved screen (cylinder):

<a-cylinder
  src="#video360"
  radius="10"
  height="5"
  theta-length="120"
  rotation="0 180 0"
  position="0 2 -5"
></a-cylinder>


🔹 Considerations

  • Autoplay restrictions: modern browsers require muted + playsInline for autoplay to work.
  • SharePoint internal videos: if the video is stored in a Document Library, you may need to fetch it using SPHttpClient and convert to a Blob URL.
  • Performance: A-Frame is more general-purpose than Photo-Sphere-Viewer, so bundle size is larger, but it enables future expansion (3D models, AR, WebXR).

🔹 Conclusion

By integrating A-Frame into an SPFx WebPart, we can offer flexible 360° video playback inside SharePoint Online pages. Depending on the use case, users can switch between cinema mode (flat or curved screens) and immersive mode (full 360° sphere).

This approach combines SharePoint’s secure hosting with A-Frame’s VR capabilities, enabling engaging and interactive training, product demos, and immersive storytelling directly in corporate intranets.

Edvaldo Guimrães Filho Avatar

Published by