Webview or Link

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.?

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!.

1 Like

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?


ok , its clear , thanks :grinning_face_with_smiling_eyes:

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…


Thank you @Darren_Murphy, I will have a look !

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]);

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() {
.everyMinutes(10) // Run every 10 minutes