Pulse — Research articles truly linking: nested-route fix (2026-08-22)
Pulse — Research articles truly linking: nested-route fix (2026-08-22)
Reported by: Young — "research article still not link and deep research — the title is there but when list no content for it." Chart confirmed FIXED by Young ✅. Fixed by: Sol, verified SSR + headless client at mobile viewport. ✅ Live at pulse.youngle.au
Root cause: Nuxt 4 nested-route trap
pages/research.vue (the index) + pages/research/[slug].vue (article) coexisting made
Nuxt 4 treat the index as a parent route for the :slug() child. The parent has no
<NuxtPage/> outlet → the article component never rendered. Every /research/{slug} URL
(real or fake) served the index page. This is why "title shows in the related list but
tapping shows no content" — the list card linked to a URL that rendered the index.
Contrast: /stock/:ticker and /quote/:ticker are top-level dynamic routes (no sibling
.vue page) → they always worked.
Fix
pages/article/[slug].vue— article page moved to its own top-level dir (the proven-working pattern)pages/research/(nested) removed;research.vueis standalone index againpages/research.vue— related-research cards now link/article/{slug}
Verified
/article/datacentre-materials→ H1 "The Floor Under AI",article-bodypresent, title tag "The Floor Under AI — Pulse" (SSR)/article/{all 4 real slugs}→ H1 + body render; fake slug → fallback, no crash/researchclient render → 5 article cards linking/article/..., arrow affordance, 10 ticker→/stock links intact, zero stale/research/{slug}hrefs- Rebuilt + restarted; service active
Files changed
pages/article/[slug].vue(new, from research/slug.vue)pages/research.vue— link target → /article/{slug}- removed
pages/research/[slug].vue(nested route that swallowed the child)
Reported by: Young — "chart still not loading, research articles still not link" (after the first fix pass). Fixed by: Sol, verified in headless Chromium at mobile viewport. ✅ Live at pulse.youngle.au
The real chart bug (v5 API)
First-pass fix addressed the bars API (ASX: prefix) — that was necessary but NOT sufficient.
The chart STILL drew nothing because lightweight-charts v5 removed the v4 series methods:
addCandlestickSeries() / addHistogramSeries() / addLineSeries() no longer exist in v5.
Only chart.addSeries(CandlestickSeries, opts) works. The old calls threw inside the
try/catch in fetchBars() → loaded=true → empty chart committed silently.
Also fixed in the same component:
containerIdwasMath.random()-based → SSR/client id mismatch → getElementById miss. Now deterministic from symbol:lwc-${symbol}.- Duplicated D/W/1M/60 row (page + component) → removed component's internal row, page's row drives the prop; component syncs via watch.
Verified: headless screenshot of /stock/SEMI now shows green/red candles, blue MA9, volume bars, price axis $20–52, date axis 2026/Apr/Jul. PNG 19.9KB → 33.6KB after fix.
Research article links — confirmed working
SSR + client render both show 5 article anchors (/research/{slug}) with → affordance,
plus 10 ticker→/stock links. Article detail pages render full content
("The Floor Under AI" etc.). The earlier "not link" report was stale-cache related:
nginx now sends Cache-Control: no-cache, no-store on HTML and
public, max-age=31536000, immutable on /_nuxt/ hashed assets so devices can never
serve a stale page across rebuilds.
Files changed
components/TradingViewChart.vue— v5 addSeries API, deterministic containerId, removed duplicate timeframe row, prop sync watchserver/api/bars.ts— strip ASX: exchange prefix (from prior pass)pages/research.vue— article cards min-h-44px + arrow affordance (prior pass)- nginx
pulse.youngle.au— cache-control: no-cache HTML / immutable hashed assets
Reported by: Young — "Research none of the article is link" + "Stock missing chart" (linked lightweight-charts repo). Fixed by: Sol (with prior Nova/Mira dispatch work). ✅ Live at pulse.youngle.au
Root causes
- Stock chart empty —
TradingViewChartpassessymbol="ASX:SEMI"(TradingView format) butserver/api/bars.tssanitized toASXSEMIthen appended.AX→ YahooASXSEMI.AX→ 404 →{"bars":[],"error":"fetch failed"}→ blank chart with no error shown. Fix: strip^ASXprefix in bars.ts; bothSEMIandASX:SEMInow work. Verified: D=255 bars, 1M=24, W=106. lightweight-charts confirmed in the client bundle (161KB chunk). - Research articles not visibly links — the article cards had anchors but zero link affordance
on mobile (no arrow/read-more cue) and sub-44px tap targets, so they read as plain text cards.
Fix: full-row
min-h-[44px]cards with a trailing→arrow + translate-on-hover.
Verified
/api/bars?ticker=ASX:SEMI&range=D|W|1M→ bars returned, no error/stock/SEMIHTTP 200;/researcharticle cards = 5 anchors with arrows; all article detail pages 200- All routes single header, hamburger intact
Files changed
server/api/bars.ts— stripASXexchange prefix from tickerpages/research.vue— article cards: min-h-44px, arrow affordance, hover state
Reported by: Young — "Pulse keeps freezing and still missing or doesn't load on mobile." Dispatched: Nova (A2A :8303) via Sol. Completed + verified by Sol after Nova hit its turn limit mid-task. Status: ✅ Fixed & live at pulse.youngle.au
Root causes (4)
- backdrop-filter containing block —
AppHeader.vueheader hadbackdrop-blur-sm.backdrop-filtermakes the header a containing block forposition: fixeddescendants, so the mobile drawer + backdrop positioned relative to the header box, not the viewport. Result: drawer body + account button floated over the podcast card, drawer clipped into the ticker strip. This is also why the page felt frozen — the drawer's scroll-lock ran against a mispositioned overlay. Fix: removedbackdrop-blur-sm+ teleported drawer & backdrop to<body>(<Teleport to="body">) so no ancestor style can ever trap them again. - Duplicate header (chat/research) —
chat.vueandresearch.vueeach embedded<AppHeader />whileapp.vuealready renders it globally → 2 stacked nav bars. Fix: removed page-level<AppHeader />; single header everywhere now. - Suspended ticker blocking quote chain — QUB (trade suspended) sat in the
quotes.ts/public-movers.tsticker arrays; the stale-quote fetch hung the chain → public-movers API took seconds (felt frozen). Fix (Nova): dropped QUB from those arrays./api/public-moversnow responds in ~1ms. - Audio metadata never loaded — podcast
<audio preload="none">showed0:00 / 0:00until tapped (read as frozen). Fix:preload="metadata"on index + podcast players so duration loads with the page. - Tab bar clipped at viewport edge — index tab rail (
Markets / Most active / Daily gainers / Daily losers) truncated without scroll affordance. Fix:snap-x-railswipe rail with edge-fade mask + scroll-snap.
Verified
- All routes 200:
//watch/research/podcast/chat/account/stock/SEMI - Exactly one
<header>and one hamburger (aria-label="Open navigation menu") per page backdrop-blur-smgone from header; Teleport present in build- API latency: markets-overview 0.36s, public-movers 1ms, news/brief/podcast <1ms, full page 53ms
- Hydration:
authedis now arefset inonMounted(no server/client localStorage mismatch)
Files changed
components/AppHeader.vue— Teleport drawer+backdrop, removed blur, authed refpages/index.vue— snap-x-rail tabs, audio preload=metadatapages/podcast.vue— audio preload=metadatapages/chat.vue,pages/research.vue— removed duplicate AppHeaderserver/api/quotes.ts,server/api/public-movers.ts— dropped suspended QUB (Nova)
Eve Privacy Policy
Effective: 2026-08-09 · Project: ~/.eve (Eve — Michio Kushi Macrobiotic Counsellor)
Paper Trading — Content & Reporting Design
Owner: Mira (content + reporting) · Automation: Min's engine (ledger/fills/journal/risk) Capital: $50,000 paper · Styles: Trend / Range / Breakout / Momentum Core thesis: Theme-first, uranium at the core · Tranched entries · Level alerts Audience: General — teaches as it reports. CommSec-brokerage tone.

