# Webview or Link

**URL:** <https://community.glideapps.com/t/webview-or-link/27464>\
**Category:** Ask for Help\
**Created:** [June 1, 2021, 9:18am UTC](https://community.glideapps.com/t/webview-or-link/27464 "2021-06-01T09:18:50Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![AyS\_0908](https://sea2.discourse-cdn.com/flex002/user_avatar/community.glideapps.com/ays_0908/32/27349_2.png) [@AyS\_0908](https://community.glideapps.com/u/AyS_0908)\
**Post date:** [June 1, 2021, 9:18am UTC](https://community.glideapps.com/t/webview-or-link/27464/1 "2021-06-01T09:18:50Z")

</div>

Hi, I want my users to be able to enter a www. address and

- see it in webview if the www. accepts it
- or display a link.

Is there a way to automatically check that webview works for a given www.?  
Thanks

---

<div class="post-metadata">

**Author:** ![Manu\_Marea](https://sea2.discourse-cdn.com/flex002/user_avatar/community.glideapps.com/manu_marea/32/21714_2.png) [@Manu\_Marea](https://community.glideapps.com/u/Manu_Marea)\
**Post date:** [June 1, 2021, 9:34am UTC](https://community.glideapps.com/t/webview-or-link/27464/2 "2021-06-01T09:34:47Z")

</div>

Webview is for embedding into the app , link to reach an app starting from the app , i have to say that Glides manages the external link quite well writing ‘loading while it loads and putting a shortcut in the left upper side that makes the external link and the user experience to look like as within the app .Both rely on how fast is the service you’re calling there ,so optimizing with gtmetrix for example is king!.

---

<div class="post-metadata">

**Author:** ![AyS\_0908](https://sea2.discourse-cdn.com/flex002/user_avatar/community.glideapps.com/ays_0908/32/27349_2.png) [@AyS\_0908](https://community.glideapps.com/u/AyS_0908)\
**Post date:** [June 1, 2021, 4:41pm UTC](https://community.glideapps.com/t/webview-or-link/27464/3 "2021-06-01T16:41:21Z")

</div>

Thank you @Manu_Marea.  
My question was not clear enough: in some case, external websites cannot be displayed via webview (I suppose that it is due to restrictions that these websites put in their code).  
In this case, we should enable our users to access this external website via a “link component”.

My objective is to display either a “webview component” or a “link component” according to the possibility (or not) of displaying the external website in webview.  
 → But, is it possible to test upfront if an url (that I don’t know since entered by the user) will be displayed in webview?

Thanks

---

<div class="post-metadata">

**Author:** ![Manu\_Marea](https://sea2.discourse-cdn.com/flex002/user_avatar/community.glideapps.com/manu_marea/32/21714_2.png) [@Manu\_Marea](https://community.glideapps.com/u/Manu_Marea)\
**Post date:** [June 1, 2021, 5:03pm UTC](https://community.glideapps.com/t/webview-or-link/27464/4 "2021-06-01T17:03:42Z")

</div>

ok , its clear , thanks 😄

---

<div class="post-metadata">

**Author:** ![Darren\_Murphy](https://sea2.discourse-cdn.com/flex002/user_avatar/community.glideapps.com/darren_murphy/32/47326_2.png) [@Darren\_Murphy](https://community.glideapps.com/u/Darren_Murphy)\
**Post date:** [June 1, 2021, 5:03pm UTC](https://community.glideapps.com/t/webview-or-link/27464/5 "2021-06-01T17:03:56Z")

</div>

I can’t think of any way to do it with Glide, but it could be done with a bit of Apps Script - which would of course mean a delay…

> **[Check If a Website Can Be Embedded in an IFrame With Node.js](https://schier.co/blog/check-if-a-website-can-be-embedded-in-an-iframe-with-nodejs)**
>
> I've been working on a new project recently that requires previewing external web pages in an iframe. This feature is not always possible though because websites can prevent themselves from showing in iframes by setting the x-frame-options header....

---

<div class="post-metadata">

**Author:** ![AyS\_0908](https://sea2.discourse-cdn.com/flex002/user_avatar/community.glideapps.com/ays_0908/32/27349_2.png) [@AyS\_0908](https://community.glideapps.com/u/AyS_0908)\
**Post date:** [June 1, 2021, 7:40pm UTC](https://community.glideapps.com/t/webview-or-link/27464/6 "2021-06-01T19:40:03Z")

</div>

Thank you @Darren_Murphy, I will have a look !

---

<div class="post-metadata">

**Author:** ![AyS\_0908](https://sea2.discourse-cdn.com/flex002/user_avatar/community.glideapps.com/ays_0908/32/27349_2.png) [@AyS\_0908](https://community.glideapps.com/u/AyS_0908)\
**Post date:** [March 20, 2023, 11:42am UTC](https://community.glideapps.com/t/webview-or-link/27464/7 "2023-03-20T11:42:26Z")

</div>

Hi, in case some want to check if the **Webview** component is **authorized** by a website (to avoid displaying the “grey” screen), the following script enables it. Once the status is indicated, we can use “visibility conditions” to display or not the webview component.

I use it in Google Sheet with my “url” being in column K (cf. 11 below) and the returned “status” being in column AP (cf. 42 below).  
NB: it is probably feasible to use it in Google Table…

I hope this is clear and helps…

function runBis() {  
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(‘AI LIST’);  
const lastRow = sheet.getLastRow();  
const scriptProperties = PropertiesService.getScriptProperties();  
const checkpoint = parseInt(scriptProperties.getProperty(‘CHECKPOINTbis’) || ‘2’);

console.log(`Starting at checkpoint: ${checkpoint}, lastRow: ${lastRow}`);

const numRowsToProcess = 150; // Number of rows to process in each run  
const endRow = Math.min(checkpoint + numRowsToProcess - 1, lastRow);  
const statusUpdates = ;

for (let i = checkpoint; i \<= endRow; i++) {  
const urlCell = sheet.getRange(i, 11);  
const statusCell = sheet.getRange(i, 42);  
const url = urlCell.getValue();  
const status = statusCell.getValue();

```
console.log(`Processing row: ${i}, url: ${url}, status: ${status}`);

if (url && !status) {
  const xFrameOptions = getXFrameOptionsBis(url);
  
  if (xFrameOptions === "DENY" || xFrameOptions === "SAMEORIGIN") {
    statusUpdates.push({row: i, status: 'iFrame KO'});
  } else {
    statusUpdates.push({row: i, status: 'iFrame OK'});
  }
}

```

}

// Batch update the status column  
if (statusUpdates.length \> 0) {  
const statusRange = sheet.getRange(statusUpdates[0].row, 42, statusUpdates.length, 1);  
const statusValues = statusUpdates.map(update =\> [update.status]);  
statusRange.setValues(statusValues);  
}

scriptProperties.setProperty(‘CHECKPOINTbis’, (endRow + 1).toString());  
}

function getXFrameOptionsBis(url) {  
try {  
const response = UrlFetchApp.fetch(url, { muteHttpExceptions: true, followRedirects: false });  
const headers = response.getHeaders();

```
if ('x-frame-options' in headers) {
  return headers['x-frame-options'].toUpperCase();
}

if ('X-Frame-Options' in headers) {
  return headers['X-Frame-Options'].toUpperCase();
}

```

} catch (e) {  
// Error fetching URL  
}

return ‘iFrame OK’; // Return “iFrame OK” if the headers do not contain any “x-frame-options” information  
}

function createTrigger() {  
ScriptApp.newTrigger(‘runBis’)  
.timeBased()  
.everyMinutes(10) // Run every 10 minutes  
.create();  
}
