Embed Web page from 3rd-party site into dashboard (iframe or otherwise)

The example @Chris_C linked to was done using the concepts in the following help article:

The article includes some sample markup. It’s an HTML page with an iframe. In the menu example, it’s basically just a menu that changes which embedded SharpTools dashboard is displayed in the iframe. But we’ve seen examples where multiple iframes were used to mix SharpTools content alongside external content.

There’s a few codesandbox examples linked within the article that you can play around with.

There’s a project by the Google Chrome team called Puppeteer which enables you to take ‘screenshots’ of a page. It would definitely be more of a developer type project though as you’d need to automate the screenshots and storing the screenshots somewhere.

We’ve been bouncing around the idea of Custom Components - the ability to build custom components to integrate third party resources (eg. To Do lists, Weather, Spotify, etc). The same concept could potentially allow you to iframe in other sites directly into a SharpTools dashboard. I’ve noted your feedback under this request and will be sure to post back here if/when we circle back on the idea.

Edit: Custom Tiles are now available! :tada: You can find documentation at the following link:

:man_technologist:t4: Custom Tiles | SharpTools Docs

1 Like

Thanks for the link to puppeteer, I’m going to have to try that. I was looking for screenshots as a service from reading the posts above but most of them have low limits on free tier.

@josh I just grabbed this image from airnow.gov, well the page that this image came from using puppeteer! Thanks for the pointer to that :slight_smile: Now I can add this to my tablet after I figure out how to automatically trim it… unless puppeteer can capture based on x,y coords, that I’ll have to read up on.

image

2 Likes

From a quick glance at their documentation, it looks like you could even select a specific element on the page. A puppeteer script like the following worked for me in the puppeteer demo environment:

const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://www.airnow.gov/?city=Frisco&state=TX&country=USA', {waitUntil: 'networkidle0',});
await page.waitForSelector('.aq-dial-container > .aq-dial');  //wait for the element to render
const element = await page.$('.aq-dial-container > .aq-dial'); //get the element as an object
await element.screenshot({path: 'airquality.png'}); // screenshot the element in puppeteer  
await browser.close();

image

If you want to get fancy and clear out the background from the gauge, you could inject a bit of scripting…

Script for transparent gauge
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://www.airnow.gov/?city=Frisco&state=TX&country=USA', {waitUntil: 'networkidle0',});
//inject a script to make everything in the element hierarchy transparent
await page.evaluate(() => {
  document.body.style.background = 'transparent';
  document.getElementsByClassName('marquee')[0].style.background = null;
  document.getElementsByClassName('marquee')[0].style.backgroundColor = 'transparent';
})
await page.waitForSelector('.aq-dial-container > .aq-dial');  //wait for the element to render
const element = await page.$('.aq-dial-container > .aq-dial'); //get the element as an object
await element.screenshot({path: 'airquality.png'}); // screenshot the element in puppeteer  
await browser.close();
2 Likes

Saved me a lot of time trying to use clip: coordinates, size and then having to deal with the background :slight_smile:

@Shai_Dotan, you may be interested to check out the puppeteer @josh mentioned. I remembered you tried to load a COVID19 dashboard page as screenshot to be displayed as part of your dashboard, and the challenge was the dashboard site requires a click before the dashboard is rendered. It seems you should be able to resolve that using page.click(selector) in puppeteer.

I just setup a docker ( buildkite/ docker-puppeteer) running on my NAS to generate the screenshot of the the city’s Covid19 dashboard site every 12 hours, and a media tile pointing to the generated screenshot image on my NAS, and used it in my dashboard.

2 Likes

Now we just need an icon for Coved!

1 Like

This is too much SW for HW guy like me. Can you please make a short movie explaining how to do that ?

@josh, just FYI this works beautifully with Microsoft PowerApps. Not sure how familiar you are with Powerapps, But I have made multiple apps that my company uses. And it hit me that those apps can be ran through a web browser. So I made a chore chart list for my kids to use and it works perfectly. Powerapps can be made to display or do basically anything that you need.

2 Likes

James , can you do the same for me:
קורונה 2020
No need to click nothing, just want the 1st table.

@Shai_Dotan, see below for a quick code example using puppeteer to screenshot the first t able in קורונה 2020, and you may need to update the code based on your needs as this is just a quick reference for you. You will need to install Node.js and NPM on the device where this script is going to be running, ex windows, raspberry PI, and etc. (I am running this on my NAS server.)

const puppeteer = require('puppeteer');
const merge = require('merge-img');
const { default: mergeImg } = require('merge-img');
const pause = (seconds) => new Promise(res => setTimeout(res, seconds * 1000));

let getCovid = async () =>{
    const browser = await puppeteer.launch({ 
        defaultViewport:{width:1200, height:800},
        headless: true,
        args: ['--no-sandbox', '--disable-setuid-sandbox']
    });
    const page = await browser.newPage();    
    await page.goto('https://newmedia.calcalist.co.il/data_journalism/corona/index.html');
    await page.waitForSelector('.info1300');     
    const element = await page.$('.info1300');  
    // await element.screenshot({path: './screenshots/table.png'});
    let imgTable = await element.screenshot();

    await page.waitForSelector('.head-and-sub._50');     
    const header = await page.$('.head-and-sub._50');  
    // await header.screenshot({path: './screenshots/header.png'});
    let imgHeader = await header.screenshot();
    // await page.waitFor(5000);
    // await page.screenshot({path: './screenshots/example.png'});    
    await browser.close();    
    let mergedImg = await merge([imgHeader, imgTable], {direction: true, align: "center"});
    mergedImg.write('./screenshots/merged.png');
    await pause(3600*6); // Run every 6 hours
    await getCovid();
}
//main
(async () => {
    try{
        await getCovid()
    }
    catch (err){
        console.error(err);
    }
})();

-EDIT-
Updated the code example to take screenshots of both the head title and table, and then merge into a single image.

2 Likes

Perfectly Work !! Thanks alot for your support.
To anyone want to use you need:

  1. Make sure you have a folder called “screenshots” in the same folder, so the code can output the image to.
  2. run : “npm install merge-img” to make it works before launching “node ScreenShot.js”
  3. Share your “screenshots” folder to Google Drive , using Google Drive desktop
  4. Use that:
    Dashboard background image not showing anymore - #4 by josh
    in order to make your “merged.png” available in SharTools.
    And if you don’t familiar to Node and NPM watch the following:
  5. YouTube in order to install :
    https://youtu.be/epH81xhS6mk
  6. YouTube in order to create project:
    https://youtu.be/xUqK8VFhu64
2 Likes

If you’re taking votes on this, please count me in! This is functionality I’d also love to have.

1 Like

I just moved this thread into the Feature Requests category, so you can vote on it now. If you refresh the page and scroll up to the top, you should see an option to vote on this post now.

1 Like

Can you share a step-by-step of how to do this for someone who has a technical background, but who’s never used PowerApps?

If you’re looking to display a list, you can do it in Google Sheets and export the table as an image. Pretty sure @josh or @James posted about it before.

1 Like

Unfortunately, I’m specifically looking to do an iFrame.

:tada:This is now possible with Custom Tiles. You can either:

  • Create a Custom Tile using the URL option for each site you want
  • Use the Refreshable URL Embed custom tile if you want to be able to embed sites without having to define them in advance and want to optionally add a periodic refresh.

:point_down::point_down:That being said, I’m looking for feedback! :point_down::point_down:

Should this feature request be closed out?

The new Custom Tile feature functionally accomplishes the original request, but I’m contemplating if something like the Refreshable URL Embed custom tile linked above should be a native feature rather than requiring the import of a custom tile - basically making it more discoverable and easier to use.

The challenge is that many sites block being embedded and it’s not something that can be detected in modern browsers – different browsers handle this differently with some showing an error within the iframe and some not being very apparent that there even is an issue. As such, I’m wondering if coming to the community and seeing the discussion could actually be a helpful stop in the user journey.

For example, here’s what Chrome on a Windows PC looks like with a site that disallows embedding: :frowning:

image

1 Like

Person who figures out how can we embed blocked webpages too… I would personally buy that person a couple of beers.
I would also buy few beers to that person who tells me that there is some kind of floating buttons for Windows that hangs top of the browser. Buttons would allow user to get back to SharpTools dashboard page in full screen mode if user has opened a new full screen tab.

1 Like

Wuuooohh, those are a bunch of beers ! :beers: