A growing collection of embeddable HTML/CSS/JS widgets and Google Apps Script components for Google Sites. Drop any snippet into a Google Sites Embed block to add dynamic, interactive content — no server required.
| Widget | Description | API Key? | Folder |
|---|---|---|---|
| ⏰ Time & Date | Live clock and calendar | None | snippets/time-and-date/ |
| 💬 Quote of the Day | Inspirational quotes | None | snippets/quote-of-day/ |
| 📜 Poem of the Day | Classic poetry daily | None | snippets/poem-of-day/ |
| 📖 Word of the Day | Vocabulary builder | None | snippets/word-of-day/ |
| 💡 Idea of the Day | Creative daily prompts | None | snippets/idea-of-day/ |
| 🖼️ Art of the Day | Met Museum masterpieces | None | snippets/art-of-day/ |
| 🔬 Science Fact of the Day | Curated STEM facts | None | snippets/science-fact-of-day/ |
| Curated destination guide | None | snippets/travel-deal-of-day/ |
|
| ☁️ Weather Widget | Current weather + forecast | OpenWeatherMap (free) | snippets/weather/ |
| 📰 News Ticker | Scrolling RSS headlines | None (rss2json optional) | snippets/news-ticker/ |
| 📈 Stock Ticker | Live or simulated stocks | Finnhub (free, optional) | snippets/stock-ticker/ |
Apps Script versions (server-side, no CORS issues) are in apps-script/:
| Component | Folder |
|---|---|
| Weather Widget | apps-script/weather/ |
| News Ticker | apps-script/news-ticker/ |
| Stock Ticker | apps-script/stock-ticker/ |
- 🚀 How to Embed in Google Sites
⚠️ Google Sites Gotchas- Widget Reference
- 🗂️ Repository Structure
- 🔑 API Key Summary
- Open your Google Site in edit mode.
- Insert → Embed → Embed code tab.
- Paste the entire contents of the snippet's
index.htmlfile. - Click Next → Insert.
- Resize the embedded block as needed.
- Go to script.google.com and create a New Project.
- Copy the contents of
Code.gsinto theCode.gseditor tab. - Click + to add a new file → HTML → name it
index(no extension needed). - Copy the contents of
index.htmlinto that tab. - Fill in any configuration values (API keys, city name, etc.) in
Code.gs. - Click Deploy → New deployment → select type Web app.
- Set Execute as: Me, Who has access: Anyone.
- Click Deploy and copy the web app URL.
- In Google Sites: Insert → Embed → By URL → paste the web app URL.
⚠️ "Google hasn't verified this app" warning: On first authorization, Google shows a consent screen warning that the app is unverified. This is normal for any personal Apps Script project you deploy yourself. Click Advanced → Go to [Your Project Name] (unsafe) to grant the required permissions. The script only accesses URLs you configure (OpenWeatherMap, RSS feeds, etc.) — no data leaves your Google account except those specific fetch calls.
Google Sites is notoriously strict with embedded code — it wraps everything in sandboxed iframes,
blocks many external scripts, and throws CORS errors if you try to fetch from APIs that don't explicitly
allow cross-origin requests. The split between snippets/ (client-side) and apps-script/
(server-side via UrlFetchApp) is the recommended workaround for these limitations.
Google Sites embed blocks have a fixed pixel height set by the site editor. Inside that iframe,
100vh refers to 100% of the iframe's height, not the device screen. If the iframe is 400 px
tall but the content naturally wants 450 px, using 100vh or min-height: 100vh creates an
unwanted double scrollbar. All snippets in this repo use height: auto on the body to avoid this.
Resize the embed block in Google Sites to fit your content instead.
When you first deploy and authorize an Apps Script Web App, Google displays a consent screen saying the app is unverified. This is expected for any personal script you deploy yourself. Click Advanced → Go to [Your Project Name] (unsafe) to proceed. The script only accesses the external URLs you configure (weather API, RSS feeds, etc.).
Google Sites iframes block target="_top" and target="_parent" by default. The only safe way to
navigate out of a Google Sites embed is target="_blank". All links in these widgets already use
target="_blank" rel="noopener noreferrer".
The quote-of-day snippet calls api.quotable.io, which has experienced intermittent 502/503
downtime. The built-in fallback array of 7 curated quotes ensures the widget is never blank, even
when the API is unavailable.
Google Sites dynamically resizes embed blocks on mobile. All widgets use clamp() for font sizes
and auto-fill/minmax grid columns to reflow gracefully. If you use card-mode layouts (e.g.,
Stock Ticker COMPACT_MODE = false), test the embed at a narrow width (≈ 320 px) in the Sites
preview and widen the embed block or reduce minmax minimums if content overflows.
The Apps Script backends (apps-script/) use CacheService.getScriptCache() to store API
responses for 5 minutes. On a high-traffic site this prevents blowing through the free tiers of
OpenWeatherMap (1,000 calls/day) or Alpha Vantage (25 calls/day) — up to 288 visitors per day can
hit the weather widget while only consuming a single API call.
File: snippets/time-and-date/index.html
API: None — pure JavaScript, works offline
Recommended embed height: 280 px
Displays a live clock (12-hour with AM/PM), current date, day of the week, and week-of-year info. Updates every second.
File: snippets/quote-of-day/index.html
API: quotable.io — free, no key required
Recommended embed height: 380 px
Fetches a random inspirational quote on each load, with author attribution and topic tags. Includes "New Quote" and "Copy & Share" buttons. Falls back to a curated list if the API is unavailable.
File: snippets/poem-of-day/index.html
API: poetrydb.org — free, no key required
Recommended embed height: 480 px
Displays a classic poem from the PoetryDB open database. Uses a daily seed to show the same poem to all visitors on the same day. Includes a scrollable verse area and a "Copy Text" button.
Configuration (inside the file):
const USE_DAILY_SEED = true; // true = same poem all day; false = random each loadFile: snippets/word-of-day/index.html
API: None — curated built-in word list
Recommended embed height: 480 px
Rotates through 30+ carefully selected English words, keyed by day-of-year so all visitors see the same word each day. Each entry includes:
- Phonetic pronunciation
- Part of speech
- Full definition
- Contextual example sentence
- Etymology
File: snippets/idea-of-day/index.html
API: None — curated built-in list
Recommended embed height: 520 px
Displays one creative, actionable idea per day from a 30-idea curated collection covering personal growth, creativity, learning, wellness, and more. Each idea includes a description and 4-step action plan.
File: snippets/art-of-day/index.html
API: Metropolitan Museum of Art Collection API — free, no key required
Recommended embed height: 620 px
Fetches a painting from the Met's open collection, displaying the image, title, artist, date, medium, and a link to the full entry on the Met website.
Configuration (inside the file):
const DEPARTMENT_ID = 11; // European Paintings
// Other options: 21 = Modern Art | 6 = Asian Art | 9 = Drawings & PrintsFile: snippets/science-fact-of-day/index.html
API: None — curated built-in list
Recommended embed height: 460 px
Rotates through 30 verified science facts spanning physics, astronomy, biology, chemistry, geology, and more. Each fact includes a plain-language explanation, the relevant scientific field, and a cited source. Keyed by day-of-year for consistency.
File: snippets/travel-deal-of-day/index.html
API: None — curated built-in list
Recommended embed height: 640 px
Showcases a destination from a curated list of 15 global travel spots, including:
- Budget classification
- Travel style tag
- Best season to visit
- Estimated average flight cost
- Local travel tip
- Must-see experiences
- Direct link to Google Flights
For real-time pricing: Integrate with the Skyscanner API, Amadeus for Developers, or Google Flights.
Files:
snippets/weather/index.html— standalone embed (API key in browser)apps-script/weather/Code.gs+index.html— server-side (recommended)
API: OpenWeatherMap — free tier: 1,000 calls/day
Recommended embed height: 600 px
Displays current conditions, feels-like temperature, humidity, wind speed, visibility, pressure, sunrise/sunset, and a 5-day forecast. Supports both °F and °C toggle.
Quick start (standalone):
- Get a free API key at openweathermap.org/api.
- Open
snippets/weather/index.htmland replaceYOUR_API_KEYnear the top:
const API_KEY = 'abc123yourkey';
const DEFAULT_CITY = 'London,UK'; // optional default- Embed the file in Google Sites.
⚠️ Security note: Embedding an API key in client-side HTML exposes it to anyone who inspects the page source. For production use, deploy the Apps Script version (apps-script/weather/) — the key stays server-side.
Files:
snippets/news-ticker/index.html— standalone embed (fetches RSS via rss2json.com)apps-script/news-ticker/Code.gs+index.html— server-side (recommended)
API: rss2json.com (standalone) or any RSS feed (Apps Script)
Recommended embed height: 48 px (ticker) or 400+ px (card mode)
Displays a horizontally scrolling news ticker from any RSS feed. Set COMPACT_MODE = false for a card-list layout.
Configuration:
// In snippets/news-ticker/index.html:
const COMPACT_MODE = true; // or false for card list
const RSS_FEED_URL = 'https://feeds.bbci.co.uk/news/rss.xml';
const RSS2JSON_KEY = ''; // optional paid key
const TICKER_SPEED = '40s'; // lower = faster
const MAX_ITEMS = 20;Suggested RSS feeds:
| Source | URL |
|---|---|
| BBC News | https://feeds.bbci.co.uk/news/rss.xml |
| Reuters | https://feeds.reuters.com/reuters/topNews |
| Google News (US) | https://news.google.com/rss?hl=en-US&gl=US&ceid=US:en |
| AP News | https://apnews.com/index.rss |
| NPR | https://feeds.npr.org/1001/rss.xml |
Files:
snippets/stock-ticker/index.html— standalone embed (Finnhub or simulated data)apps-script/stock-ticker/Code.gs+index.html— server-side (recommended)
API: Finnhub (free: 60 calls/min) or Alpha Vantage (free: 25 calls/day)
Recommended embed height: 52 px (ticker) or 320+ px (card mode)
Shows a scrolling stock price ticker with color-coded up/down indicators. Falls back to deterministic simulated data if no API key is set (good for demos). Set COMPACT_MODE = false for a card grid.
Configuration:
// In snippets/stock-ticker/index.html:
const COMPACT_MODE = true; // or false for card grid
const FINNHUB_KEY = 'yourkey'; // leave blank for simulated data
const TICKER_SPEED = '35s';
const REFRESH_MS = 15 * 60 * 1000; // 15-minute auto-refresh
const STOCKS = [
{ symbol: 'AAPL', name: 'Apple' },
{ symbol: 'MSFT', name: 'Microsoft' },
// ... add/remove symbols here
];google-site-script-snippets/
│
├── snippets/ Pure HTML/CSS/JS — embed directly in Google Sites
│ ├── time-and-date/
│ │ └── index.html
│ ├── quote-of-day/
│ │ └── index.html
│ ├── poem-of-day/
│ │ └── index.html
│ ├── word-of-day/
│ │ └── index.html
│ ├── idea-of-day/
│ │ └── index.html
│ ├── art-of-day/
│ │ └── index.html
│ ├── science-fact-of-day/
│ │ └── index.html
│ ├── travel-deal-of-day/
│ │ └── index.html
│ ├── weather/
│ │ └── index.html
│ ├── news-ticker/
│ │ └── index.html
│ └── stock-ticker/
│ └── index.html
│
└── apps-script/ Google Apps Script projects — deploy as Web App
├── weather/
│ ├── Code.gs
│ └── index.html
├── news-ticker/
│ ├── Code.gs
│ └── index.html
└── stock-ticker/
├── Code.gs
└── index.html
| Widget | API | Free Tier | Key Required |
|---|---|---|---|
| Quote of the Day | quotable.io | Unlimited | ✗ |
| Poem of the Day | poetrydb.org | Unlimited | ✗ |
| Art of the Day | Met Museum API | Unlimited | ✗ |
| Weather | OpenWeatherMap | 1,000 calls/day | ✓ |
| News Ticker | RSS (direct) | — | ✗ |
| News Ticker | rss2json.com | Rate-limited | Optional |
| Stock Ticker | Finnhub | 60 req/min | Optional |
| Stock Ticker | Alpha Vantage | 25 calls/day | Optional |
MIT — free to use, modify, and distribute.