Add promotional banner for iframe-embedded games#144
Conversation
When the game is loaded inside an iframe (e.g., wordlespielen.de embedding /de), show a subtle bottom banner after game completion that links to wordle.global. The banner has a 30-day dismiss cooldown and does not show for direct visitors or standalone PWA users.
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughA new embed banner feature is introduced to detect when the game runs inside an iframe, conditionally display a banner after game completion, persist dismissal state via localStorage for 30 days, and expose the dismissal functionality through the global window interface and frontend module. Changes
Sequence Diagram(s)sequenceDiagram
participant Game as Game Logic
participant Embed as Embed Module
participant DOM as DOM
participant Storage as localStorage
Game->>Embed: isEmbedded()?
Embed->>Embed: Check window.self !== window.top
Embed-->>Game: true/false
alt Game Won/Lost
Game->>Embed: showBanner()
Embed->>DOM: Display embed-banner
Note over DOM: Banner visible to user
DOM->>DOM: User clicks dismiss
DOM->>Embed: dismiss()
Embed->>Storage: Set dismissal state + timestamp
Embed->>DOM: Hide banner
else User Refreshes/Revisits
Embed->>Storage: Check dismissal timestamp
Storage-->>Embed: Timestamp (if within 30 days)
alt Within 30-day window
Embed->>DOM: Keep banner hidden
else Expired
Embed->>DOM: Allow banner to show
end
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
webapp/templates/game.html (1)
654-656: Consider localizing the banner text for consistency.The text "Play Wordle in 65+ languages" is hardcoded in English, while other UI strings use localized values from
language.config.ui. Consider using a pattern like:<strong>{{ language.config.ui.play_in_languages or "Play Wordle in 65+ languages" }}</strong>This maintains English as a fallback while allowing localization for languages that provide translations.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@webapp/templates/game.html` around lines 654 - 656, Replace the hardcoded banner text with a localized UI value so translations can override it: find the strong tag rendering "Play Wordle in 65+ languages" and use the template variable language.config.ui.play_in_languages with an English fallback (e.g. "Play Wordle in 65+ languages") so the banner pulls from the same localization source as other UI strings.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@webapp/templates/game.html`:
- Around line 652-662: The anchor in the embed banner uses a nonexistent
attribute language.code causing a broken link; update the href to use the
correct attribute language.language_code (i.e., change "{{ language.code }}" to
"{{ language.language_code }}") so the Visit link points to the proper URL;
ensure any other occurrences within the embed banner (e.g., text or JS
interactions referencing language.code) are also updated to
language.language_code and keep the existing rel/target attributes and
dismissEmbedBanner() button unchanged.
---
Nitpick comments:
In `@webapp/templates/game.html`:
- Around line 654-656: Replace the hardcoded banner text with a localized UI
value so translations can override it: find the strong tag rendering "Play
Wordle in 65+ languages" and use the template variable
language.config.ui.play_in_languages with an English fallback (e.g. "Play Wordle
in 65+ languages") so the banner pulls from the same localization source as
other UI strings.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 76d5589b-ff56-4da5-b705-1657dcccb50b
📒 Files selected for processing (5)
frontend/src/embed.tsfrontend/src/game.tsfrontend/src/main.tsfrontend/src/style.csswebapp/templates/game.html
| <!-- Embed banner for iframe embeds --> | ||
| <div id="embed-banner" class="embed-banner" style="display: none;"> | ||
| <div style="flex: 1;"> | ||
| <strong>Play Wordle in 65+ languages</strong> | ||
| </div> | ||
| <a href="https://wordle.global/{{ language.code }}" target="_blank" rel="noopener" | ||
| style="background: white; color: #2d6a4f; border: none; padding: 8px 16px; border-radius: 6px; font-weight: 600; cursor: pointer; text-decoration: none; transition: transform 0.1s;"> | ||
| Visit | ||
| </a> | ||
| <button class="dismiss" onclick="dismissEmbedBanner()">×</button> | ||
| </div> |
There was a problem hiding this comment.
Critical: language.code attribute does not exist — link will be broken.
The Language class defines self.language_code (see webapp/app.py line 647), not self.code. This will cause the "Visit" link to render incorrectly (empty or error).
Compare with line 2 of this template which correctly uses language.language_code, and lines 49/55/59/71/87 which use language.config.language_code.
🐛 Proposed fix
- <a href="https://wordle.global/{{ language.code }}" target="_blank" rel="noopener"
+ <a href="https://wordle.global/{{ language.language_code }}" target="_blank" rel="noopener"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@webapp/templates/game.html` around lines 652 - 662, The anchor in the embed
banner uses a nonexistent attribute language.code causing a broken link; update
the href to use the correct attribute language.language_code (i.e., change "{{
language.code }}" to "{{ language.language_code }}") so the Visit link points to
the proper URL; ensure any other occurrences within the embed banner (e.g., text
or JS interactions referencing language.code) are also updated to
language.language_code and keep the existing rel/target attributes and
dismissEmbedBanner() button unchanged.
- Cache isEmbedded as a const (never changes during session) - Lazy-evaluate isDismissed() only when showing banner (avoid localStorage read for non-embedded users) - Remove redundant isEmbedded() checks in game.ts callers — let showBanner() own its own guard logic - Call both embed.showBanner() and pwa.showBanner() unconditionally (each no-ops when not applicable), fixing gameLost inconsistency - Extract shared .bottom-banner CSS base class to deduplicate styles - Move embed banner inline styles to CSS classes
Summary
wordle.global/{lang}in a new tab, converting iframe users into direct visitorsWhy
At least 5 sites are iframing wordle.global without attribution. Google doesn't credit iframes as backlinks, so we get zero SEO benefit. This banner promotes our brand directly to those users and drives organic traffic back to us.
Files changed
frontend/src/embed.ts— New module: iframe detection, banner show/hide/dismiss logicfrontend/src/game.ts— Show embed banner instead of PWA banner when in iframefrontend/src/main.ts— ExposedismissEmbedBannerto windowfrontend/src/style.css— Banner styling (fixed bottom, green gradient)webapp/templates/game.html— Banner HTMLTest plan
pnpm build,pnpm test)Summary by CodeRabbit
Release Notes