When performing a hard refresh on a lesson page (e.g., C# Playground), the code editor briefly displays a default or cached code snippet for approximately 2–3 seconds before the lesson instructions and runtime fully load. This behavior may confuse users, as it appears that the lesson content is incorrect or mismatched during initialization.
🧪 Steps to Reproduce
Navigate to any lesson in the SpikerSoft Learn platform (e.g., learn.spikersoft.com/tools/csharp-playground?lessonId=100).
Perform a hard refresh (Ctrl + F5 or Cmd + Shift + R).
Observe the code editor immediately after the refresh.
Notice that a code snippet (e.g., using System; class Program { ... }) appears briefly before the correct lesson instructions load.
✅ Expected Behavior
The lesson should load seamlessly without displaying temporary or cached code.
If loading feedback is necessary, it should use a consistent loading animation or progress indicator rather than showing placeholder content.
❌ Actual Behavior
Cached or default code appears for 2–3 seconds after a hard refresh.
The lesson instructions and correct code replace it once the runtime finishes loading.
The transition feels abrupt and may mislead users into thinking the lesson has changed or failed to load properly.
📸 Evidence
The first screenshot shows the temporary code snippet visible immediately after a hard refresh.
The second screenshot shows the correct lesson instructions once the runtime finishes loading.
🧠 Possible Root Cause
The lesson component renders before the runtime or lesson data is fully hydrated.
Cached editor state is displayed during initialization.
Missing conditional rendering or delayed masking of the editor while lesson data loads.
🔧 Suggested Fix
Add a loading overlay or UI mask to hide the editor until the lesson data is ready.
Prevent cached or placeholder code from rendering before the runtime handshake completes.
Replace the raw text with a localized loading message (e.g., “Loading lesson…”).
Test across all playgrounds to ensure consistent behavior.
🔍 Additional Recommendation
Audit all Learn > language_name playgrounds (C#, Python, JS, C++, SQL, Regex, x86) to confirm that no cached code or placeholder content appears during initialization or refresh.
### 🧩 Summary
When performing a **hard refresh** on a lesson page (e.g., C# Playground), the code editor briefly displays a default or cached code snippet for approximately **2–3 seconds** before the lesson instructions and runtime fully load. This behavior may confuse users, as it appears that the lesson content is incorrect or mismatched during initialization.
### 🧪 Steps to Reproduce
1. Navigate to any lesson in the SpikerSoft Learn platform (e.g., `learn.spikersoft.com/tools/csharp-playground?lessonId=100`).
2. Perform a **hard refresh** (`Ctrl + F5` or `Cmd + Shift + R`).
3. Observe the code editor immediately after the refresh.
4. Notice that a code snippet (e.g., `using System; class Program { ... }`) appears briefly before the correct lesson instructions load.
### ✅ Expected Behavior
The lesson should load seamlessly without displaying temporary or cached code.
If loading feedback is necessary, it should use a **consistent loading animation** or **progress indicator** rather than showing placeholder content.
### ❌ Actual Behavior
- Cached or default code appears for 2–3 seconds after a hard refresh.
- The lesson instructions and correct code replace it once the runtime finishes loading.
- The transition feels abrupt and may mislead users into thinking the lesson has changed or failed to load properly.
### 📸 Evidence
The first screenshot shows the temporary code snippet visible immediately after a hard refresh.
The second screenshot shows the correct lesson instructions once the runtime finishes loading.
### 🧠 Possible Root Cause
- The lesson component renders before the runtime or lesson data is fully hydrated.
- Cached editor state is displayed during initialization.
- Missing conditional rendering or delayed masking of the editor while lesson data loads.
### 🔧 Suggested Fix
1. Add a **loading overlay** or **UI mask** to hide the editor until the lesson data is ready.
2. Prevent cached or placeholder code from rendering before the runtime handshake completes.
3. Replace the raw text with a localized loading message (e.g., “Loading lesson…”).
4. Test across all playgrounds to ensure consistent behavior.
### 🔍 Additional Recommendation
Audit all **Learn > language_name playgrounds** (C#, Python, JS, C++, SQL, Regex, x86) to confirm that no cached code or placeholder content appears during initialization or refresh.
### 🌐 Environment
- **URL:** learn.spikersoft.com/tools/csharp-playground?lessonId=100
- **Version:** v2026.06.09a
- **Browser:** Edge (latest)
- **OS:** Windows 10.0
- **User:** Jorge (logged in)
Root cause: the shared LanguageRunner (used by every playground) seeds the editor with the language's sandbox starter code at construction. On a hard refresh of ?lessonId=N, the real lesson starter only lands after the async catalog + attempt fetch finishes (~2-3 s), so the default snippet was visible the whole time.
Fix: when the first paint is a lesson deep link (?lessonId / ?resume=1), the editor is masked with a localized "Loading lesson…" placeholder until the lesson resolves. The mask only ever engages on deep links — sandbox landings render the editor immediately — and lifts even when the deep link is rejected (stale/locked lesson), so it can't get stuck.
Because the fix is in the shared runner, it covers all playgrounds at once (C#, Python, JS, C/C++, SQL, Regex, x86), per the audit recommendation. Regression tests added.
Fix is up: spikersoft-angular PR #37.
**Root cause:** the shared `LanguageRunner` (used by every playground) seeds the editor with the language's *sandbox* starter code at construction. On a hard refresh of `?lessonId=N`, the real lesson starter only lands after the async catalog + attempt fetch finishes (~2-3 s), so the default snippet was visible the whole time.
**Fix:** when the first paint is a lesson deep link (`?lessonId` / `?resume=1`), the editor is masked with a localized "Loading lesson…" placeholder until the lesson resolves. The mask only ever engages on deep links — sandbox landings render the editor immediately — and lifts even when the deep link is rejected (stale/locked lesson), so it can't get stuck.
Because the fix is in the shared runner, it covers all playgrounds at once (C#, Python, JS, C/C++, SQL, Regex, x86), per the audit recommendation. Regression tests added.
Resolved — spikersoft-angular PR #37 merged to master and the pipeline is green.
Resolution notes
Root cause: the shared LanguageRunner seeds the editor with the language's sandbox starter code at construction (codeSignal = resolveInitialStarterCode()). On a hard refresh of a lesson deep link (?lessonId=N), the real lesson starter only arrives after the async catalog + attempt fetch (loadCatalogAndRoute()) completes (~2–3 s), and the template had no loading gate around the editor — so the default snippet (using System; class Program { ... }) was visible for that whole window.
Fix: the runner now captures at construction whether the first paint was a lesson deep link (?lessonId=N or ?resume=1) and exposes lessonBootPending(). While pending, the editor is masked with a localized "Loading lesson…" placeholder (pulsing hourglass, sized to match the editor so the layout doesn't jump). The mask lifts only after the lesson attempt is seeded, so the editor never shows unrelated code; rejected deep links (stale/locked lesson, unauthenticated-offline) also lift the mask and fall back to sandbox, so it cannot get stuck.
Audit coverage: the fix lives in the shared LanguageRunner, so all playgrounds are covered at once — C#, Python, JavaScript, C, C++, SQL, Regex, x86 — per the issue's recommendation. Plain sandbox landings (no lesson params) are unaffected and render the editor on the first frame.
i18n: added librariesPlatform.languageRunner.loadingLesson in English ("Loading lesson…") and Spanish ("Cargando lección…").
Tests: new regression spec language-runner-boot-mask.spec.ts (4 tests) holds the catalog fetch open to assert the mid-boot frame: mask shown + editor absent during boot, lesson starter present when the mask lifts, ?resume=1 masked too, sandbox never masked, rejected deep links recover cleanly.
Drive-by CI fix: added a shared testing/storage-test-setup.ts localStorage/sessionStorage polyfill and wired it into the SQL runner's vitest config, fixing 11 latent localStorage.clear is not a function failures that surfaced when this change invalidated the cached test result.
Closing.
Resolved — spikersoft-angular PR #37 merged to master and the pipeline is green.
**Resolution notes**
- **Root cause:** the shared `LanguageRunner` seeds the editor with the language's *sandbox* starter code at construction (`codeSignal = resolveInitialStarterCode()`). On a hard refresh of a lesson deep link (`?lessonId=N`), the real lesson starter only arrives after the async catalog + attempt fetch (`loadCatalogAndRoute()`) completes (~2–3 s), and the template had no loading gate around the editor — so the default snippet (`using System; class Program { ... }`) was visible for that whole window.
- **Fix:** the runner now captures at construction whether the first paint was a lesson deep link (`?lessonId=N` or `?resume=1`) and exposes `lessonBootPending()`. While pending, the editor is masked with a localized **"Loading lesson…"** placeholder (pulsing hourglass, sized to match the editor so the layout doesn't jump). The mask lifts only after the lesson attempt is seeded, so the editor never shows unrelated code; rejected deep links (stale/locked lesson, unauthenticated-offline) also lift the mask and fall back to sandbox, so it cannot get stuck.
- **Audit coverage:** the fix lives in the shared `LanguageRunner`, so all playgrounds are covered at once — C#, Python, JavaScript, C, C++, SQL, Regex, x86 — per the issue's recommendation. Plain sandbox landings (no lesson params) are unaffected and render the editor on the first frame.
- **i18n:** added `librariesPlatform.languageRunner.loadingLesson` in English ("Loading lesson…") and Spanish ("Cargando lección…").
- **Tests:** new regression spec `language-runner-boot-mask.spec.ts` (4 tests) holds the catalog fetch open to assert the mid-boot frame: mask shown + editor absent during boot, lesson starter present when the mask lifts, `?resume=1` masked too, sandbox never masked, rejected deep links recover cleanly.
- **Drive-by CI fix:** added a shared `testing/storage-test-setup.ts` localStorage/sessionStorage polyfill and wired it into the SQL runner's vitest config, fixing 11 latent `localStorage.clear is not a function` failures that surfaced when this change invalidated the cached test result.
Closing.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
🧩 Summary
When performing a hard refresh on a lesson page (e.g., C# Playground), the code editor briefly displays a default or cached code snippet for approximately 2–3 seconds before the lesson instructions and runtime fully load. This behavior may confuse users, as it appears that the lesson content is incorrect or mismatched during initialization.
🧪 Steps to Reproduce
learn.spikersoft.com/tools/csharp-playground?lessonId=100).Ctrl + F5orCmd + Shift + R).using System; class Program { ... }) appears briefly before the correct lesson instructions load.✅ Expected Behavior
The lesson should load seamlessly without displaying temporary or cached code.
If loading feedback is necessary, it should use a consistent loading animation or progress indicator rather than showing placeholder content.
❌ Actual Behavior
📸 Evidence
The first screenshot shows the temporary code snippet visible immediately after a hard refresh.
The second screenshot shows the correct lesson instructions once the runtime finishes loading.
🧠 Possible Root Cause
🔧 Suggested Fix
🔍 Additional Recommendation
Audit all Learn > language_name playgrounds (C#, Python, JS, C++, SQL, Regex, x86) to confirm that no cached code or placeholder content appears during initialization or refresh.
🌐 Environment
Fix is up: spikersoft-angular PR #37.
Root cause: the shared
LanguageRunner(used by every playground) seeds the editor with the language's sandbox starter code at construction. On a hard refresh of?lessonId=N, the real lesson starter only lands after the async catalog + attempt fetch finishes (~2-3 s), so the default snippet was visible the whole time.Fix: when the first paint is a lesson deep link (
?lessonId/?resume=1), the editor is masked with a localized "Loading lesson…" placeholder until the lesson resolves. The mask only ever engages on deep links — sandbox landings render the editor immediately — and lifts even when the deep link is rejected (stale/locked lesson), so it can't get stuck.Because the fix is in the shared runner, it covers all playgrounds at once (C#, Python, JS, C/C++, SQL, Regex, x86), per the audit recommendation. Regression tests added.
Resolved — spikersoft-angular PR #37 merged to master and the pipeline is green.
Resolution notes
LanguageRunnerseeds the editor with the language's sandbox starter code at construction (codeSignal = resolveInitialStarterCode()). On a hard refresh of a lesson deep link (?lessonId=N), the real lesson starter only arrives after the async catalog + attempt fetch (loadCatalogAndRoute()) completes (~2–3 s), and the template had no loading gate around the editor — so the default snippet (using System; class Program { ... }) was visible for that whole window.?lessonId=Nor?resume=1) and exposeslessonBootPending(). While pending, the editor is masked with a localized "Loading lesson…" placeholder (pulsing hourglass, sized to match the editor so the layout doesn't jump). The mask lifts only after the lesson attempt is seeded, so the editor never shows unrelated code; rejected deep links (stale/locked lesson, unauthenticated-offline) also lift the mask and fall back to sandbox, so it cannot get stuck.LanguageRunner, so all playgrounds are covered at once — C#, Python, JavaScript, C, C++, SQL, Regex, x86 — per the issue's recommendation. Plain sandbox landings (no lesson params) are unaffected and render the editor on the first frame.librariesPlatform.languageRunner.loadingLessonin English ("Loading lesson…") and Spanish ("Cargando lección…").language-runner-boot-mask.spec.ts(4 tests) holds the catalog fetch open to assert the mid-boot frame: mask shown + editor absent during boot, lesson starter present when the mask lifts,?resume=1masked too, sandbox never masked, rejected deep links recover cleanly.testing/storage-test-setup.tslocalStorage/sessionStorage polyfill and wired it into the SQL runner's vitest config, fixing 11 latentlocalStorage.clear is not a functionfailures that surfaced when this change invalidated the cached test result.Closing.