npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@michael.schmetter/iframemanager

v1.1.3

Published

GDPR friendly iframe manager written in vanilla js

Downloads

7

Readme

Demo   |   Features   |   Installation   

License: MIT Size Stable version

IframeMananger is a lightweight javascript plugin which helps you comply with GDPR by completely removing iframes initially and setting a notice relative to that service. Iframes are loaded only after consent.

The plugin was mainly developed to aid CookieConsent with iframe management.

Table of Contents

Features

  • Lightweight
  • Complies with GDPR
  • Multilanguage support
  • Automatic/custom thumbnail support *
  • Allows to integrate any service which uses iframes
  • Improves website performance:
    • no <iframe> tags on first page load
    • lazyloads thumbnails
    • lazyloads iframes
  • Can be integrated with any cookie consent solution

Installation

  1. Download the latest release or use via CDN:

    https://cdn.jsdelivr.net/gh/orestbida/[email protected]/dist/iframemanager.js
    https://cdn.jsdelivr.net/gh/orestbida/[email protected]/dist/iframemanager.css
  2. Import script + stylesheet:

    <html>
      <head>
        ...
        <link rel="stylesheet" href="iframemanager.css">
      </head>
      <body>
        ...
        <script src="iframemanager.js" defer></script>
      <body>
    </html>
  3. Configure and run:

      • Create a .js file (e.g. app.js) and import it in your html markup:

        <body>
            ...
            <script src="iframemanager.js" defer></script>
            <script src="app.js" defer></script>
        <body>
      • Configure iframemanager inside app.js:

        (function(){
        
            var manager = iframemanager();
        
            // Example with youtube embed
            manager.run({
                currLang: 'en',
                services : {
                    youtube : {
                        embedUrl: 'https://www.youtube-nocookie.com/embed/{data-id}',
                        thumbnailUrl: 'https://i3.ytimg.com/vi/{data-id}/hqdefault.jpg',
                        iframe : {
                            allow : 'accelerometer; encrypted-media; gyroscope; picture-in-picture; fullscreen;',
                        },
                        cookie : {
                            name : 'cc_youtube'
                        },
                        languages : {
                            en : {
                                notice: 'This content is hosted by a third party. By showing the external content you accept the <a rel="noreferrer" href="https://www.youtube.com/t/terms" title="Terms and conditions" target="_blank">terms and conditions</a> of youtube.com.',
                                loadBtn: 'Load video',
                                loadAllBtn: 'Don\'t ask again'
                            }
                        }
                    }
                }
            });
        })();
    • <body>
        ...
        <script src="iframemanager.js" defer></script>
      
        <!-- Inline script -->
        <script>
          window.addEventListener('load', function(){
      
              var manager = iframemanager();
      
              // Example with youtube embed
              manager.run({
                  currLang: 'en',
                  services : {
                      youtube : {
                          embedUrl: 'https://www.youtube-nocookie.com/embed/{data-id}',
                          thumbnailUrl: 'https://i3.ytimg.com/vi/{data-id}/hqdefault.jpg',
                          iframe : {
                              allow : 'accelerometer; encrypted-media; gyroscope; picture-in-picture; fullscreen;',
                          },
                          cookie : {
                              name : 'cc_youtube'
                          },
                          languages : {
                              en : {
                                  notice: 'This content is hosted by a third party. By showing the external content you accept the <a rel="noreferrer" href="https://www.youtube.com/t/terms" title="Terms and conditions" target="_blank">terms and conditions</a> of youtube.com.',
                                  loadBtn: 'Load video',
                                  loadAllBtn: 'Don\'t ask again'
                              }
                          }
                      }
                  }
              });
          });
        </script>
      <body>
  4. Create a div (will contain the iframe) with data-service and data-id attributes:

    <div data-service="youtube" data-id="<video-id>"></div>

Configuration options

All available options for the <div> element:

<div
    data-service="<service-name>"
    data-id="<resource-id>"
    data-params="<iframe-query-parameters>"
    data-thumbnail="<path-to-image>"
    data-autoscale
    data-ratio="<x:y>">
</div>
  • data-service : [String, Required] name of the service (must also be defined in the config. object)
  • data-id : [String, Required] unique id of the resource (example: video id)
  • data-params : [String] iframe query parameters
  • data-thumbnail : [String] path to custom thumbnail
  • data-ratio : [String] custom aspect ratio (Available values.)[v1.1.0]
  • data-autoscale : specify for responsive iframe (fill parent width + scale proportionally)

How to set attributes on the iframe element

You can set set attribute by using the following syntax

  • data-iframe-<attribute> [String] note: replace <attribute> with a valid attribute name. [v1.1.0]

Example:

<div
    data-service="..."
    data-id="..."
    data-autoscale
    data-iframe-id="myGoogleMapsEmbed"
    data-iframe-loading="lazy"
    data-iframe-frameborder="0">
</div>

All available options for the config. object:

{
    currLang: 'en',     // current language of the notice (must also be defined in the "languages" object below)
    autoLang: false,    // if enabled => use current client's browser language
                        // instead of currLang [OPTIONAL]

    services : {
        myservice : {

            embedUrl: 'https://myservice_embed_url>/{data-id}',

            // set valid url for automatic thumbnails   [OPTIONAL]
            thumbnailUrl: 'https://<myservice_embed_thumbnail_url>/{data-id}',

            // global iframe settings (apply to all iframes relative to current service) [OPTIONAL]
            iframe : {
                allow : 'fullscreen',           // iframe's allow attribute
                params : 'mute=1&start=21'      // iframe's url query parameters

                // function run for each iframe configured with current service
                onload : function(data_id, setThumbnail){
                    console.log("loaded iframe with data-id=" + data_id);
                }
            },

            // cookie is set if the current service is accepted
            cookie : {
                name : 'cc_youtube',            // cookie name
                path : '/',                     // cookie path          [OPTIONAL]
                samesite : 'lax',               // cookie samesite      [OPTIONAL]
                domain : location.hostname      // cookie domain        [OPTIONAL]
            },

            languages : {
                en : {
                    notice: 'Html <b>notice</b> message',
                    loadBtn: 'Load video',          // Load only current iframe
                    loadAllBtn: 'Don\'t ask again'  // Load all iframes configured with this service + set cookie
                }
            }
        },

        anotherservice : {
            ...
        }
    }
}

Any other property specified inside the iframe object, will be applied directly to the iframe element as an attribute.

Example: add frameborder and style attributes:

{
    // ...

    services : {
        myservice : {
            // ...

            iframe : {
                // ...

                frameborder: '0',
                style: 'border: 4px solid red;'
            }
        }
    }
}

Note: thumbnailUrl can be static string, dynamic string or a function:

  • static string : "https://path_to_image/image.png"
  • dynamic string : "https://myservice_embed_url/{data-id}"
  • function :
    ...
    thumbnailUrl : function(data_id, setThumbnail){
        // fetch thumbnail url here based on data_id of the current element ...
        var url = 'fetched_url';
    
        // pass obtained url to the setThumbnail function
        setThumbnail(url);
    },
    ...

APIs

The plugin exposes 3 main methods:

  • .run(<config_object>)
  • .acceptService(<service_name>)
  • .rejectService(<service_name>)

Example usage:

// accept specific service only
manager.acceptService('youtube');

// accept all services (for example if user has given full consent to cookies)
manager.acceptService('all');

// reject specific service
manager.rejectService('youtube');

// reject all services (for example when user opts out of cookies)
manager.rejectService('all');

Both acceptService and rejectService work the same way:

  1. set/erase cookie
  2. create/remove iframes

Configuration examples

  • // Example with youtube embed
    manager.run({
        currLang: 'en',
        services : {
            youtube : {
                embedUrl: 'https://www.youtube-nocookie.com/embed/{data-id}',
                thumbnailUrl: 'https://i3.ytimg.com/vi/{data-id}/hqdefault.jpg',
                iframe : {
                    allow : 'accelerometer; encrypted-media; gyroscope; picture-in-picture; fullscreen;',
                },
                cookie : {
                    name : 'cc_youtube'
                },
                languages : {
                    en : {
                        notice: 'This content is hosted by a third party. By showing the external content you accept the <a rel="noreferrer" href="https://www.youtube.com/t/terms" title="Terms and conditions" target="_blank">terms and conditions</a> of youtube.com.',
                        loadBtn: 'Load video',
                        loadAllBtn: 'Don\'t ask again'
                    }
                }
            }
        }
    });
  • // Example with dailymotion embed
    manager.run({
        currLang: 'en',
        services : {
            dailymotion : {
                embedUrl: 'https://www.dailymotion.com/embed/video/{data-id}',
    
                // Use dailymotion api to obtain thumbnail
                thumbnailUrl: function(id, setThumbnail){
    
                    var url = "https://api.dailymotion.com/video/" + id + "?fields=thumbnail_large_url";
                    var xhttp = new XMLHttpRequest();
    
                    xhttp.onreadystatechange = function() {
                        if (this.readyState == 4 && this.status == 200) {
                            var src = JSON.parse(this.response).thumbnail_large_url;
                            setThumbnail(src);
                        }
                    };
    
                    xhttp.open("GET", url, true);
                    xhttp.send();
                },
                iframe : {
                    allow : 'accelerometer; encrypted-media; gyroscope; picture-in-picture; fullscreen;',
                },
                cookie : {
                    name : 'cc_dailymotion'
                },
                languages : {
                    'en' : {
                        notice: 'This content is hosted by a third party. By showing the external content you accept the <a rel="noreferrer" href="https://www.dailymotion.com/legal/privacy?localization=en" title="Terms and conditions" target="_blank">terms and conditions</a> of dailymotion.com.',
                        loadBtn: 'Load video',
                        loadAllBtn: 'Don\'t ask again'
                    }
                }
            }
        }
    });
  • // Example with vimeo embed
    manager.run({
        currLang: 'en',
        services : {
            vimeo : {
                embedUrl: 'https://player.vimeo.com/video/{data-id}',
    
                thumbnailUrl: function(id, setThumbnail){
    
                    var url = "https://vimeo.com/api/v2/video/" + id + ".json";
                    var xhttp = new XMLHttpRequest();
    
                    xhttp.onreadystatechange = function() {
                        if (this.readyState == 4 && this.status == 200) {
                            var src = JSON.parse(this.response)[0].thumbnail_large;
                            setThumbnail(src);
                        }
                    };
    
                    xhttp.open("GET", url, true);
                    xhttp.send();
                },
                iframe : {
                    allow : 'accelerometer; encrypted-media; gyroscope; picture-in-picture; fullscreen;',
                },
                cookie : {
                    name : 'cc_vimeo'
                },
                languages : {
                    'en' : {
                        notice: 'This content is hosted by a third party. By showing the external content you accept the <a rel="noreferrer" href="https://vimeo.com/terms" title="Terms and conditions" target="_blank">terms and conditions</a> of vimeo.com.',
                        loadBtn: 'Load video',
                        loadAllBtn: 'Don\'t ask again'
                    }
                }
            }
        }
    });
  • // Example with simple twitch stream/channel
    // IMPORTANT: replace "yourWebsite.com" with your own website
    manager.run({
        currLang: 'en',
        services : {
            twitch : {
                embedUrl: 'https://player.twitch.tv/?{data-id}&parent=localhost&parent=yourWebsite.com',
                iframe : {
                    allow : 'accelerometer; encrypted-media; gyroscope; picture-in-picture; fullscreen;',
                },
                cookie : {
                    name : 'cc_twitch'
                },
                languages : {
                    'en' : {
                        notice: 'This content is hosted by a third party. By showing the external content you accept the <a rel="noreferrer" href="https://www.twitch.tv/p/en/legal/terms-of-service/" title="Terms and conditions" target="_blank">terms and conditions</a> of twitch.com.',
                        loadBtn: 'Load stream',
                        loadAllBtn: 'Don\'t ask again'
                    }
                }
            }
        }
    });
  • More "presets" for other service to come ...

Available data-ratio

Horizontal aspect ratio:

  • 1:1, 2:1, 3:2, 5:2, 4:3, 16:9, 16:10, 20:9, 21:9

Vertical aspect ratio:

  • 9:16, 9:20

License

Distributed under the MIT License. See LICENSE for more information.

Note

Not all services (example: twitch) allow automatic/easy thumbnail fetch.