2025 System Prompt:
The HTML file must run entirely offline, without external libraries
https://script.google.com/macros/s/AKfycbzo0Ks82A6UvFjciXeo3XvJNCNuSjh6uVLDJjJ1sfA3FxHS4B8aF8Yi4rp7YtJ-ZOyeyQ/exec
| https://script.google.com/macros/s/AKfycbzo0Ks82A6UvFjciXeo3XvJNCNuSjh6uVLDJjJ1sfA3FxHS4B8aF8Yi4rp7YtJ-ZOyeyQ/exec |
| in SLS? |
Short version: it isn’t SLS “failing,” it’s SLS protecting itself.
Just prompt AI to avoid using CDN libraries.
|
When you add that Google Apps Script (GAS) web-app URL as a Media item, SLS loads it inside a sandboxed <iframe> with a strict Content-Security Policy (CSP) and allow-list. Your GAS page pulls JavaScript/CSS from external CDNs (e.g., ajax.googleapis.com, apis.google.com, gstatic.com, cdnjs, cdn.jsdelivr.net, etc.). Those domains are not on SLS’s allow-list, so the browser blocks them. Once those CDN files don’t load, your app can’t initialize—hence “not running properly.”
What’s happening under the hood (typical console errors)
-
Refused to load the script 'https://ajax.googleapis.com/.../jquery.min.js' because it violates the site's Content Security Policy 'script-src ...'. -
Refused to connect to 'https://apis.google.com/js/api.js' because it’s not in 'connect-src'. -
Fonts/CSS also get blocked (e.g.,
fonts.googleapis.com / fonts.gstatic.com), breaking layout or icons. -
If your GAS uses Google APIs that inject additional scripts, those are blocked too.
-
In some cases, GAS pages add their own frame headers; if
X-Frame-Optionsisn’t set to ALLOWALL in Apps Script (HtmlService.XFrameOptionsMode.ALLOWALL), cross-site embedding gets blocked even before CSP.
Why this is expected in SLS
-
SLS Media runs in a restricted iframe (“no third-party scripts”) to protect students and comply with MOE security. Only assets hosted on the same origin or on pre-approved domains can execute.
-
GAS web apps are served from
*.googleusercontent.comand call out to other Google CDNs; these cross-origin calls don’t satisfy SLS’s CSP for Media.
How to make it work (practical fixes)
-
Bundle everything, no CDNs.
Replace<script src="https://.../jquery.min.js">and other CDN links with local, self-hosted files. Ship a single HTML file with embedded JS/CSS or a zipped package that references local assets only. (Use a bundler like Vite/Rollup/Webpack to inline.) -
Avoid Google-injected scripts.
Don’t rely ongapi, Google Picker, Google Identity, or Apps Script services that inject remote JS. If you must, this should be an Integrated App (LTI) rather than a Media embed. -
If you must stay on GAS:
-
In Apps Script HTML, set
HtmlService.createHtmlOutput(...).setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL)(prevents frame-blocking by your page). -
Still, the external CDNs will be blocked by SLS CSP, so you’d also need to vendor (host locally) all libraries and assets and avoid runtime calls to Google APIs.
-
-
Prefer an SLS Integrated App route for dynamic cloud apps.
Host your app on an approved domain and integrate via SLS Integrated App (LTI 1.3). This path can be allow-listed to call backends securely and is the right model for apps that need external services/APIs. -
Static HTML5 Media alternative.
Rebuild the experience as a pure HTML5 interactive (no external calls), zip it, and upload as a Media resource. This works reliably in SLS.
Quick diagnostic checklist
-
Open DevTools → Console: look for CSP “Refused to load” / “Refused to connect” errors.
-
Search your HTML for
https://links to CDNs (scripts, styles, fonts); remove/inline them. -
Ensure no runtime fetch/XHR to third-party domains.
-
If staying on GAS, set
ALLOWALLfor X-Frame and test outside SLS first, then re-embed.
Bottom line: the failure in SLS Media is because your page depends on CDN/third-party resources that SLS’s CSP blocks. The durable fix is to self-contain (bundle) the app’s JS/CSS/fonts and avoid external calls—or use the Integrated App route where such calls can be approved safely.