This is a feature request to give developers more options to configure the allow
attribute for iframes generated by HtmlService
.
The immediate use case is to enable on-device AI capabilities like Gemini Nano, which requires the host iframe to include the allow="language-model"
attribute to grant access to the Prompt API, as outlined in recent Chrome AI announcements. Without this, it's currently impossible to build Workspace Add-ons that leverage these new browser features.
Currently, add-on iframes are served with an extensive list of permissions (e.g., camera
, geolocation
, microphone
), which demonstrates that a permissions framework is already in place. To provide developers with control, we suggest a new method for the HtmlOutput
class, such as .setIframeAllow(permissionString)
. This new method could operate on a list of Google-approved permission strings, ensuring that only safe and vetted capabilities can be enabled, including the new language-model
policy.
Here is a hypothetical example of how the proposed feature would be used in Code.gs
, along with the corresponding client-side HTML.
function onOpen() {
DocumentApp.getUi()
.createMenu('Nano AI')
.addItem('Show Demo', 'showSidebar')
.addToUi();
}
function showSidebar() {
const html = HtmlService.createHtmlOutputFromFile('sidebar')
.setTitle('Gemini Nano Demo');
// --- PROPOSED NEW METHOD ---
// This would instruct Google to add the attribute to the iframe.
html.setIframeAllow('language-model');
DocumentApp.getUi().showSidebar(html);
}
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<h3>Gemini Nano Prompt Demo</h3>
<p>Model Availability: <code id="availability">checking...</code></p>
<button onclick="run()">Run Prompt</button>
<pre id="output"></pre>
<script>
const availabilityElement = document.getElementById('availability');
// Check for availability on load
(async () => {
if (window.ai) {
const availability = await window.ai.canCreateTextSession();
availabilityElement.textContent = availability;
} else {
availabilityElement.textContent = 'Not supported';
}
})();
async function run() {
// ... function to run the prompt ...
// This would fail or succeed based on the iframe permission.
}
</script>
</body>
</html>
When the sidebar is rendered, the generated <iframe>
has an extensive allow
attribute but lacks the necessary language-model
value.
<iframe src="https://n-....googleusercontent.com/userCodeAppPanel"
allow="accelerometer *; camera *; geolocation *; microphone *; ... ; web-share *">
</iframe>
This results in a check for the model's availability returning unavailable
.
With the proposed .setIframeAllow('language-model')
method, the language-model
value would be appended to the existing allow
attribute list.
<iframe src="https://n-....googleusercontent.com/userCodeAppPanel"
allow="accelerometer *; camera *; ... ; web-share *; language-model *">
</iframe>
This would grant the necessary permission, and a check for the model's availability would return readily
.
These are the steps to reproduce the current limitation:
- 1. Create a new Apps Script project bound to a Google Doc, Sheet or Slides.
- 2. Add the
Code.gs
andsidebar.html
files with the content from the code sections above. - 3. Save the project and reload the host document to see the "Nano AI" menu.
- 4. Open the sidebar via
Nano AI > Show Demo
. - 5. Observe that "Model Availability" in the sidebar shows
unavailable
. This confirms the permission issue.