{"id":2098,"date":"2018-01-10T17:04:49","date_gmt":"2018-01-10T17:04:49","guid":{"rendered":"https:\/\/ionicframework.com\/?p=2098"},"modified":"2018-01-10T17:04:49","modified_gmt":"2018-01-10T17:04:49","slug":"make-a-video-web-component-the-stencil-way","status":"publish","type":"post","link":"https:\/\/ionic.io\/blog\/make-a-video-web-component-the-stencil-way","title":{"rendered":"Make a Video Web Component, the Stencil Way"},"content":{"rendered":"<p><img decoding=\"async\" data-src=\"http:\/\/cloudinary-res.cloudinary.com\/image\/upload\/w_770,c_fill\/dpr_auto\/StecilJS_Video_Component_2000x1100_v1-2.jpg\" alt=\"\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" class=\"lazyload\" \/><noscript><img decoding=\"async\" src=\"http:\/\/cloudinary-res.cloudinary.com\/image\/upload\/w_770,c_fill\/dpr_auto\/StecilJS_Video_Component_2000x1100_v1-2.jpg\" alt=\"\" \/><\/noscript><\/p>\n<p><strong>TL;DR<\/strong><br \/>\nStencil is a JavaScript tool that enables you to build framework-independent and standards-compliant web components using technologies, such as TypeScript and JSX.<br \/>\nStencil provides APIs that makes writing fast components a breeze. These APIs &#8212; Virtual DOM, JSX, Async rendering and Reactive data-binding &#8212; equip developers with superpowers to create custom web components. Popular JavaScript frameworks, including React, Vue and Angular, all have something in common &#8211; the ability to create custom and reusable components. Check out this <a href=\"https:\/\/cloudinary.com\/blog\/getting_started_with_stenciljs\">StencilJS Guide<\/a> written by <a href=\"https:\/\/twitter.com\/codebeast\/\">Christian Nwamba<\/a> for a succinct primer on generating pure custom components.<\/p>\n<p><!--more--><\/p>\n<p>Let\u2019s start our journey by showing how to create a custom web component with Stencil. We\u2019ll use one of my favorite APIs, Cloudinary, as the functional service for which we\u2019ll craft a web component.<\/p>\n<h3>What\u2019s Cloudinary?<\/h3>\n<p><a href=\"https:\/\/cloudinary.com\/solutions\">Cloudinary<\/a> is a cloud-based, end-to-end media management solution. As a critical part of the developer stack, Cloudinary automates and streamlines your entire media asset workflow. It handles a wide variety of media types, from images, video and audio to emerging rich and interactive media types. Cloudinary\u2019s powerful APIs are used by developers to automate every stage of the media management lifecycle, including media selection, upload, analysis and administration, manipulation optimization and delivery.<\/p>\n<h3>Existing Components<\/h3>\n<p>Fortunately for developers, Cloudinary offers SDKs for different languages and frameworks, including Ruby on Rails, PHP, Angular, React, JQuery, Android, iOS, Python and JavaScript. Let\u2019s look quickly at the Cloudinary components that exist for a couple of these frameworks: Angular and React.<\/p>\n<p><strong>Angular SDK<\/strong><\/p>\n<pre><code>&lt;cl-video&gt; component. \n&lt;cl-transformation&gt; component.\n<\/code><\/pre>\n<p><a href=\"https:\/\/github.com\/cloudinary\/cloudinary_angular\">Repository<\/a><br \/>\nUsage:<\/p>\n<pre><code>   &lt;cl-video cloud-name=&quot;my_other_cloud&quot; public-id=&quot;watchme&quot; secure=&quot;true&quot; class=&quot;my-videos&quot;&gt;\n        &lt;cl-transformation overlay=&quot;text:arial_60:watchme&quot; gravity=&quot;north&quot; y=&quot;20&quot;&gt;&lt;\/cl-transformation&gt;\n   &lt;\/cl-video&gt;\n<\/code><\/pre>\n<p><strong>React SDK<\/strong><\/p>\n<pre><code>&lt;Video&gt; component. \n&lt;Transformation&gt; component.\n<\/code><\/pre>\n<p><a href=\"https:\/\/github.com\/cloudinary\/cloudinary-react\">Repository<\/a><br \/>\nUsage:<\/p>\n<pre><code>&lt;Video publicId=&quot;dog&quot; &gt;\n  &lt;Transformation width=&quot;300&quot; height=&quot;200&quot; crop=&quot;crop&quot; \/&gt;\n&lt;\/Video&gt;\n<\/code><\/pre>\n<p>In September 2017, <a href=\"https:\/\/twitter.com\/davidwalshblog\">David Walsh<\/a> wrote an <a href=\"https:\/\/davidwalsh.name\/cloudinary-vue-components\">excellent article on how to create a Cloudinary video component<\/a>. I skimmed through the blog post and decided to do the same with Stencil.<\/p>\n<h3>Stencil Component<\/h3>\n<p>Without further ado, we\u2019ll go ahead to build our Stencil component. Let\u2019s start with the component template.<\/p>\n<h4>Component Template<\/h4>\n<p>Let\u2019s take a look at the JSX for the component. In Stencil, the HTML Skeleton resides in the render method.<\/p>\n<pre><code class=\"js\">render() {\n    return (\n      &lt;div onMouseEnter={this.showPreview.bind(this)} onMouseLeave={this.hidePreview.bind(this)} class=&quot;cloudinary-video-item&quot; style={{&#039;width&#039;:`${this.width}px`,&#039;height&#039;:`${this.height}px`}}&gt;\n        &lt;div class=&quot;cloudinary-video-item-active&quot;&gt;\n          &lt;video id=&quot;previewVideo&quot; poster={this.poster} autoplay loop width={this.width} height={this.height}&gt;&lt;\/video&gt;\n        &lt;\/div&gt;\n        &lt;div class=&quot;cloudinary-video-item-video&quot;&gt;\n          &lt;video id=&quot;fullVideo&quot; autoplay controls width={this.width} height={this.height}&gt;&lt;\/video&gt;\n        &lt;\/div&gt;\n        &lt;svg\n           onClick={this.play.bind(this)}\n           xmlnsDc=&quot;http:\/\/purl.org\/dc\/elements\/1.1\/&quot;\n           xmlnsCc=&quot;http:\/\/creativecommons.org\/ns#&quot;\n           xmlnsRdf=&quot;http:\/\/www.w3.org\/1999\/02\/22-rdf-syntax-ns#&quot;\n           xmlnsSvg=&quot;http:\/\/www.w3.org\/2000\/svg&quot;\n           xmlns=&quot;http:\/\/www.w3.org\/2000\/svg&quot;\n           id=&quot;play-icon&quot;\n           version=&quot;1.1&quot;\n           height=&quot;50&quot;\n           width=&quot;50&quot;\n           viewBox=&quot;0 0 1200 1200&quot;&gt;\n          &lt;path\n             d=&quot;M 600,1200 C 268.65,1200 0,931.35 0,600 0,268.65 268.65,0 600,0 c 331.35,0 600,268.65 600,600 0,331.35 -268.65,600 -600,600 z M 450,300.45 450,899.55 900,600 450,300.45 z&quot;\n             id=&quot;path16995&quot; \/&gt;\n        &lt;\/svg&gt;\n      &lt;\/div&gt;\n    );\n  }\n<\/code><\/pre>\n<p>In the code above, there is a root div that houses three child elements. The first two elements are divs, while the last is an SVG. Next, let\u2019s configure the component and the props it will receive once it\u2019s in use.<\/p>\n<h4>Component Properties<\/h4>\n<pre><code class=\"js\">import { Element, State, Component, Prop } from &#039;@stencil\/core&#039;;\n@Component({\n  tag: &#039;cloudinary-video&#039;,\n  styleUrl: &#039;cloudinary-video.scss&#039;\n})\nexport class CloudinaryVideo {\n  @Prop() account: string;\n  @Prop() width: string;\n  @Prop() height: string;\n  @Prop() alias: string;\n  @Element() videoEl: HTMLElement;\n  @State() fullVideo: string;\n  @State() preview: string;\n  @State() poster: string;\n\u2026..\n<\/code><\/pre>\n<p>In the code above, we specified the number of properties that a user can pass to the component. <em>account<\/em>, <em>width<\/em>, <em>height<\/em>, and <em>alias<\/em>. We can specify many more, but for the sake of this article, it will be limited to just four props. To do this we can use the <code>@Prop()<\/code> decorator. <code>@Prop()<\/code> is a decorator that enables components to explicitly declare props.<\/p>\n<ul>\n<li><em>account<\/em>: Cloudinary account name of the user<\/li>\n<li><em>width<\/em>: Width of the video container<\/li>\n<li><em>height<\/em>: Height of the video container<\/li>\n<li><em>alias<\/em>: Name of the video to be played<\/li>\n<\/ul>\n<p>Next, we have the state attributes, <em>fullVideo<\/em>, <em>preview<\/em>, <em>poster<\/em>. To do this we can use the <code>@State()<\/code> decorator, which enables components to manage data internally.<\/p>\n<ul>\n<li><em>fullVideo<\/em>: URL of the complete video<\/li>\n<li><em>preview<\/em>: URL of the video preview<\/li>\n<li><em>poster<\/em>: URL of the video poster<\/li>\n<\/ul>\n<p><code>@Element()<\/code> is a decorator that enables the component to get access to the host element within the class instance. Basically, it means we can get access to the component itself and manipulate it and its child elements to achieve whatever we want.<\/p>\n<h3>Component Methods<\/h3>\n<p>These are the methods that will perform the key operations when certain events trigger in our component. In the component template, we have the <em>onMouseEnter<\/em>, <em>onMouseLeave<\/em> and <em>onClick<\/em> events.<\/p>\n<pre><code class=\"js\">  play() {\n    \/\/ Hide the preview\n    this.hidePreview();\n    \/\/ Set the state to &quot;playing&quot; for showPreview and hidePreview checks\n    this.videoEl.setAttribute(&#039;state&#039;, &#039;playing&#039;);\n    \/\/ Set the full video element src\n    this.videoEl.querySelector(&#039;#fullVideo&#039;).setAttribute(&#039;src&#039;, this.fullVideo);\n    \/\/ set the svg play button to disappear\n    this.videoEl.querySelector(&#039;svg&#039;).style.display = &#039;none&#039;;\n  }\n\n  showPreview() {\n    \/\/ If the full video is loaded and playing, ignore this event\n    if(this.videoEl.getAttribute(&#039;state&#039;) === &#039;playing&#039;) {\n      return;\n    }\n    \/\/ set the preview video to the src attribute of the video tag\n    this.videoEl.querySelector(&#039;#previewVideo&#039;).setAttribute(&#039;src&#039;, this.preview);\n  }\n\n  hidePreview() {\n    \/\/ If the full video is loaded and playing, ignore this event\n    if(this.videoEl.getAttribute(&#039;state&#039;) === &#039;playing&#039;) {\n      return;\n    }\n    \/\/ Set the video to go to the beginning\n    this.videoEl.querySelector(&#039;video&#039;).currentTime = 0;\n    \/\/ ..then pause the video\n    this.videoEl.querySelector(&#039;video&#039;).pause();\n  }\n<\/code><\/pre>\n<p>We have the <code>play<\/code>, <code>showPreview<\/code>, and <code>hidePreview<\/code> methods.<\/p>\n<p><code>play<\/code>: This method hides the preview, sets the state attribute of the component to <code>playing<\/code>, assigns the full video URL to the video element and eliminates the SVG play button at the middle of the video container.<br \/>\n<code>showPreview<\/code>: This method assigns the preview video URL to the video element. If the video is currently playing, it does nothing.<br \/>\n<code>hidePreview<\/code>: This method resets video time to the beginning of the video and pauses it. If the video is currently playing, it does nothing.<\/p>\n<p>Worthy of note is the Stencil Lifecycle method we invoked in our component.<\/p>\n<pre><code class=\"js\"> componentDidLoad() {\n    this.fullVideo = `http:\/\/res.cloudinary.com\/${this.account}\/video\/upload\/${this.alias}.mp4`;\n    this.preview = `http:\/\/res.cloudinary.com\/${this.account}\/video\/upload\/so_0,du_2\/l_video:${this.alias},fl_splice,so_12\/du_2\/fl_layer_apply\/l_video:${this.alias},fl_splice,so_24\/du_2\/fl_layer_apply\/l_video:${this.alias},fl_splice,so_36\/du_2\/fl_layer_apply\/l_video:${this.alias},fl_splice,so_48\/du_2\/fl_layer_apply\/l_video:${this.alias},fl_splice,so_80\/du_2\/fl_layer_apply\/${this.alias}.mp4`;\n    this.poster = `http:\/\/res.cloudinary.com\/${this.account}\/video\/upload\/${this.alias}.jpg`;\n  }\n<\/code><\/pre>\n<h3>Add Video Magic<\/h3>\n<p>The <code>componentDidLoad<\/code> is a lifecycle hook that is invoked when a component is loaded. In this component, we assigned the on-the-fly Cloudinary transformation URLs to the variables above.<br \/>\nThe preview video URL looks a little scary. What are all those URL parameters? Oh, that\u2019s one of the superpowers of Cloudinary. Cloudinary <a href=\"https:\/\/cloudinary.com\/documentation\/video_manipulation_and_delivery#on_the_fly_video_encoding_and_delivery\">encodes and deliver videos on-the-fly<\/a> and also <a href=\"https:\/\/cloudinary.com\/documentation\/video_manipulation_and_delivery#concatenating_videos\">applies transformations to videos<\/a> via URLs. In this URL, there is <code>fl_splice<\/code>, <code>fl_layer_apply<\/code>. These are flags you can use for overlaying videos and concatenating to the container video.<br \/>\nCheck out the documentation for several <a href=\"http:\/\/cloudinary.com\/documentation\/video_manipulation_and_delivery\">transformation tricks for video<\/a>.<\/p>\n<h3>Component CSS<\/h3>\n<p>The CSS for this component is fairly simple.<br \/>\n<em>components\/cloudinary-video\/cloudinary-video.scss<\/em><\/p>\n<pre><code class=\"css\">cloudinary-video {\n  .cloudinary-video-item {\n    position: relative;\n  }\n  .cloudinary-video-item &gt; div {\n    position: absolute;\n    top: 0;\n    left: 0;\n  }\n  .cloudinary-video-item svg {\n    position: absolute;\n    top: 40%;\n    left: 45%;\n    cursor: pointer;\n    opacity: 0.6;\n  }\n  .cloudinary-video-item svg:hover {\n    opacity: 0.9;\n  }\n  .cloudinary-video-item-active, .cloudinary-video-item-video {\n    display: block;\n  }\n}\n<\/code><\/pre>\n<h3>Using the Component<\/h3>\n<p>Using the component is as simple as:<\/p>\n<pre><code class=\"html\">  &lt;cloudinary-video\n    account=&quot;unicodeveloper&quot;\n    alias=&quot;cartoon&quot;\n    width=&quot;640&quot;\n    height=&quot;360&quot;&gt;\n  &lt;\/cloudinary-video&gt;\n<\/code><\/pre>\n<p>This code can simply be dropped into your HTML file.<br \/>\nThe code for the Cloudinary Stencil Video Component is on <a href=\"https:\/\/github.com\/unicodeveloper\/cloudinary-stencil\">GitHub<\/a>.<\/p>\n<p>There are many kinds of components that can be generated with Stencil. Stencil\u2019s API makes it easy to create standards-compliant web components as shown above. With Cloudinary, you can create robust media web components that developers can latch onto for building media-heavy web software. I look forward to seeing you create standards-compliant web components with Stencil. In the next post, you will learn how to build an image gallery with Stencil Custom Components using Cloudinary.<\/p>\n<p>Author Bio:<br \/>\nProsper Otemuyiwa is a food ninja, open source advocate and self-proclaimed developer evangelist.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>TL;DR Stencil is a JavaScript tool that enables you to build framework-independent and standards-compliant web components using technologies, such as TypeScript and JSX. Stencil provides APIs that makes writing fast components a breeze. These APIs &#8212; Virtual DOM, JSX, Async rendering and Reactive data-binding &#8212; equip developers with superpowers to create custom web components. Popular [&hellip;]<\/p>\n","protected":false},"author":59,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"publish_to_discourse":"","publish_post_category":"","wpdc_auto_publish_overridden":"","wpdc_topic_tags":"","wpdc_pin_topic":"","wpdc_pin_until":"","discourse_post_id":"","discourse_permalink":"","wpdc_publishing_response":"","wpdc_publishing_error":"","_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1],"tags":[76,25],"class_list":["post-2098","post","type-post","status-publish","format-standard","hentry","category-all","tag-stencil","tag-tutorials"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v23.0 (Yoast SEO v23.0) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Make a Video Web Component, the Stencil Way - Ionic Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/ionic.io\/blog\/make-a-video-web-component-the-stencil-way\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Make a Video Web Component, the Stencil Way\" \/>\n<meta property=\"og:description\" content=\"TL;DR Stencil is a JavaScript tool that enables you to build framework-independent and standards-compliant web components using technologies, such as TypeScript and JSX. Stencil provides APIs that makes writing fast components a breeze. These APIs &#8212; Virtual DOM, JSX, Async rendering and Reactive data-binding &#8212; equip developers with superpowers to create custom web components. Popular [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/ionic.io\/blog\/make-a-video-web-component-the-stencil-way\" \/>\n<meta property=\"og:site_name\" content=\"Ionic Blog\" \/>\n<meta property=\"article:published_time\" content=\"2018-01-10T17:04:49+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/cloudinary-res.cloudinary.com\/image\/upload\/w_770,c_fill\/dpr_auto\/StecilJS_Video_Component_2000x1100_v1-2.jpg\" \/>\n<meta name=\"author\" content=\"Prosper Otemuyiwa\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@ionicframework\" \/>\n<meta name=\"twitter:site\" content=\"@ionicframework\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Prosper Otemuyiwa\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/ionic.io\/blog\/make-a-video-web-component-the-stencil-way#article\",\"isPartOf\":{\"@id\":\"https:\/\/ionic.io\/blog\/make-a-video-web-component-the-stencil-way\"},\"author\":{\"name\":\"Prosper Otemuyiwa\",\"@id\":\"https:\/\/ionic.io\/blog\/#\/schema\/person\/a6fdb2d3eaa970dd0f24f9cab7035fa5\"},\"headline\":\"Make a Video Web Component, the Stencil Way\",\"datePublished\":\"2018-01-10T17:04:49+00:00\",\"dateModified\":\"2018-01-10T17:04:49+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/ionic.io\/blog\/make-a-video-web-component-the-stencil-way\"},\"wordCount\":919,\"commentCount\":3,\"publisher\":{\"@id\":\"https:\/\/ionic.io\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/ionic.io\/blog\/make-a-video-web-component-the-stencil-way#primaryimage\"},\"thumbnailUrl\":\"http:\/\/cloudinary-res.cloudinary.com\/image\/upload\/w_770,c_fill\/dpr_auto\/StecilJS_Video_Component_2000x1100_v1-2.jpg\",\"keywords\":[\"stencil\",\"Tutorials\"],\"articleSection\":[\"All\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/ionic.io\/blog\/make-a-video-web-component-the-stencil-way#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/ionic.io\/blog\/make-a-video-web-component-the-stencil-way\",\"url\":\"https:\/\/ionic.io\/blog\/make-a-video-web-component-the-stencil-way\",\"name\":\"Make a Video Web Component, the Stencil Way - Ionic Blog\",\"isPartOf\":{\"@id\":\"https:\/\/ionic.io\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/ionic.io\/blog\/make-a-video-web-component-the-stencil-way#primaryimage\"},\"image\":{\"@id\":\"https:\/\/ionic.io\/blog\/make-a-video-web-component-the-stencil-way#primaryimage\"},\"thumbnailUrl\":\"http:\/\/cloudinary-res.cloudinary.com\/image\/upload\/w_770,c_fill\/dpr_auto\/StecilJS_Video_Component_2000x1100_v1-2.jpg\",\"datePublished\":\"2018-01-10T17:04:49+00:00\",\"dateModified\":\"2018-01-10T17:04:49+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/ionic.io\/blog\/make-a-video-web-component-the-stencil-way#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/ionic.io\/blog\/make-a-video-web-component-the-stencil-way\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/ionic.io\/blog\/make-a-video-web-component-the-stencil-way#primaryimage\",\"url\":\"http:\/\/cloudinary-res.cloudinary.com\/image\/upload\/w_770,c_fill\/dpr_auto\/StecilJS_Video_Component_2000x1100_v1-2.jpg\",\"contentUrl\":\"http:\/\/cloudinary-res.cloudinary.com\/image\/upload\/w_770,c_fill\/dpr_auto\/StecilJS_Video_Component_2000x1100_v1-2.jpg\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/ionic.io\/blog\/make-a-video-web-component-the-stencil-way#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/ionic.io\/blog\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Make a Video Web Component, the Stencil Way\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/ionic.io\/blog\/#website\",\"url\":\"https:\/\/ionic.io\/blog\/\",\"name\":\"ionic.io\/blog\",\"description\":\"Build amazing native and progressive web apps with the web\",\"publisher\":{\"@id\":\"https:\/\/ionic.io\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/ionic.io\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/ionic.io\/blog\/#organization\",\"name\":\"Ionic\",\"url\":\"https:\/\/ionic.io\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/ionic.io\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2020\/10\/white-on-color.png\",\"contentUrl\":\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2020\/10\/white-on-color.png\",\"width\":1920,\"height\":854,\"caption\":\"Ionic\"},\"image\":{\"@id\":\"https:\/\/ionic.io\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/ionicframework\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/ionic.io\/blog\/#\/schema\/person\/a6fdb2d3eaa970dd0f24f9cab7035fa5\",\"name\":\"Prosper Otemuyiwa\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/ionic.io\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2018\/01\/image1.jpg\",\"contentUrl\":\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2018\/01\/image1.jpg\",\"caption\":\"Prosper Otemuyiwa\"},\"url\":\"https:\/\/ionic.io\/blog\/author\/prosper\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Make a Video Web Component, the Stencil Way - Ionic Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/ionic.io\/blog\/make-a-video-web-component-the-stencil-way","og_locale":"en_US","og_type":"article","og_title":"Make a Video Web Component, the Stencil Way","og_description":"TL;DR Stencil is a JavaScript tool that enables you to build framework-independent and standards-compliant web components using technologies, such as TypeScript and JSX. Stencil provides APIs that makes writing fast components a breeze. These APIs &#8212; Virtual DOM, JSX, Async rendering and Reactive data-binding &#8212; equip developers with superpowers to create custom web components. Popular [&hellip;]","og_url":"https:\/\/ionic.io\/blog\/make-a-video-web-component-the-stencil-way","og_site_name":"Ionic Blog","article_published_time":"2018-01-10T17:04:49+00:00","og_image":[{"url":"http:\/\/cloudinary-res.cloudinary.com\/image\/upload\/w_770,c_fill\/dpr_auto\/StecilJS_Video_Component_2000x1100_v1-2.jpg"}],"author":"Prosper Otemuyiwa","twitter_card":"summary_large_image","twitter_creator":"@ionicframework","twitter_site":"@ionicframework","twitter_misc":{"Written by":"Prosper Otemuyiwa","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/ionic.io\/blog\/make-a-video-web-component-the-stencil-way#article","isPartOf":{"@id":"https:\/\/ionic.io\/blog\/make-a-video-web-component-the-stencil-way"},"author":{"name":"Prosper Otemuyiwa","@id":"https:\/\/ionic.io\/blog\/#\/schema\/person\/a6fdb2d3eaa970dd0f24f9cab7035fa5"},"headline":"Make a Video Web Component, the Stencil Way","datePublished":"2018-01-10T17:04:49+00:00","dateModified":"2018-01-10T17:04:49+00:00","mainEntityOfPage":{"@id":"https:\/\/ionic.io\/blog\/make-a-video-web-component-the-stencil-way"},"wordCount":919,"commentCount":3,"publisher":{"@id":"https:\/\/ionic.io\/blog\/#organization"},"image":{"@id":"https:\/\/ionic.io\/blog\/make-a-video-web-component-the-stencil-way#primaryimage"},"thumbnailUrl":"http:\/\/cloudinary-res.cloudinary.com\/image\/upload\/w_770,c_fill\/dpr_auto\/StecilJS_Video_Component_2000x1100_v1-2.jpg","keywords":["stencil","Tutorials"],"articleSection":["All"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/ionic.io\/blog\/make-a-video-web-component-the-stencil-way#respond"]}]},{"@type":"WebPage","@id":"https:\/\/ionic.io\/blog\/make-a-video-web-component-the-stencil-way","url":"https:\/\/ionic.io\/blog\/make-a-video-web-component-the-stencil-way","name":"Make a Video Web Component, the Stencil Way - Ionic Blog","isPartOf":{"@id":"https:\/\/ionic.io\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/ionic.io\/blog\/make-a-video-web-component-the-stencil-way#primaryimage"},"image":{"@id":"https:\/\/ionic.io\/blog\/make-a-video-web-component-the-stencil-way#primaryimage"},"thumbnailUrl":"http:\/\/cloudinary-res.cloudinary.com\/image\/upload\/w_770,c_fill\/dpr_auto\/StecilJS_Video_Component_2000x1100_v1-2.jpg","datePublished":"2018-01-10T17:04:49+00:00","dateModified":"2018-01-10T17:04:49+00:00","breadcrumb":{"@id":"https:\/\/ionic.io\/blog\/make-a-video-web-component-the-stencil-way#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/ionic.io\/blog\/make-a-video-web-component-the-stencil-way"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/ionic.io\/blog\/make-a-video-web-component-the-stencil-way#primaryimage","url":"http:\/\/cloudinary-res.cloudinary.com\/image\/upload\/w_770,c_fill\/dpr_auto\/StecilJS_Video_Component_2000x1100_v1-2.jpg","contentUrl":"http:\/\/cloudinary-res.cloudinary.com\/image\/upload\/w_770,c_fill\/dpr_auto\/StecilJS_Video_Component_2000x1100_v1-2.jpg"},{"@type":"BreadcrumbList","@id":"https:\/\/ionic.io\/blog\/make-a-video-web-component-the-stencil-way#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/ionic.io\/blog"},{"@type":"ListItem","position":2,"name":"Make a Video Web Component, the Stencil Way"}]},{"@type":"WebSite","@id":"https:\/\/ionic.io\/blog\/#website","url":"https:\/\/ionic.io\/blog\/","name":"ionic.io\/blog","description":"Build amazing native and progressive web apps with the web","publisher":{"@id":"https:\/\/ionic.io\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/ionic.io\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/ionic.io\/blog\/#organization","name":"Ionic","url":"https:\/\/ionic.io\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/ionic.io\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2020\/10\/white-on-color.png","contentUrl":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2020\/10\/white-on-color.png","width":1920,"height":854,"caption":"Ionic"},"image":{"@id":"https:\/\/ionic.io\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/ionicframework"]},{"@type":"Person","@id":"https:\/\/ionic.io\/blog\/#\/schema\/person\/a6fdb2d3eaa970dd0f24f9cab7035fa5","name":"Prosper Otemuyiwa","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/ionic.io\/blog\/#\/schema\/person\/image\/","url":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2018\/01\/image1.jpg","contentUrl":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2018\/01\/image1.jpg","caption":"Prosper Otemuyiwa"},"url":"https:\/\/ionic.io\/blog\/author\/prosper"}]}},"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/posts\/2098","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/users\/59"}],"replies":[{"embeddable":true,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/comments?post=2098"}],"version-history":[{"count":0,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/posts\/2098\/revisions"}],"wp:attachment":[{"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/media?parent=2098"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/categories?post=2098"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/tags?post=2098"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}