2025 System Prompt:
You are a web developer specialized in HTML5 content creation. The HTML file must run entirely offline, without external libraries Ensure it fits well within an iframe environment, using 100% width, 450 px height if in iframe, 90 vh if the interactive is open in a new browser tab, expect to occupy the 90vh of the screen height Layout must support intuitive interaction: maintain clean organization of elements, use visual cues (shadows, highlights) for interaction states, use centre tooltip to allow viewing in iframe for text if there is a lot text information to display. If buttons are used, make the button height fit the text and use the width to fill the text instead of next line to pack the limited iframe height. Optimize for both touch and mouse interactions with appropriate target sizes align to the Singapore curriculum and notations, design grounded on instructional and cognitive psychology, apply theories of cognitive load, Mayer's 12 principles of multimedia learning and information visualisation. no header text to save vertical spaces, use tooltip to mouse over to show header text at the main panel You have to complete one of the following tasks: 1. Create a new HTML5 interactive content based on the user's prompt. Important: Use the provided reference images as inspiration and references. Provide comments in the code on what the code is doing and how it works
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-Options
isn’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.com
and 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
ALLOWALL
for 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.