116 Commits
Author SHA1 Message Date
jinhojang6 1010bab46d fix(status.app): build og:url from the canonical URL on inheriting routes 2026-08-27 01:12:37 +09:00
jinhojang6 42e8d68cf8 fix(status.app): declare canonical URLs as absolute on every route 2026-08-27 01:12:37 +09:00
jinhojang6 a8bd7cdf4c fix(status.app): merge incoming className in CodeBlock 2026-08-25 21:13:31 +09:00
jinhojang6 a37a6d5fec fix(status.app): restore code block background on content pages 2026-08-25 21:13:31 +09:00
jinhojang6 9bd0e45384 fix(status.app): fetch the specs submodule at build time 2026-08-25 01:08:16 +09:00
jinhojang6 5fcfd013d9 refactor(status.app): route the remaining same-origin URLs through SITE_URL 2026-08-25 01:08:16 +09:00
jinhojang6 3be39e4aa1 docs(status.app): document submodule and edge-cache requirements for self-hosting 2026-08-25 01:08:16 +09:00
jinhojang6 86e3659cfc fix(status.app): demote the prefooter CTA heading to h2 2026-08-25 01:08:16 +09:00
jinhojang6 ddbf70df91 fix(status.app): fail the build when the specs submodule is missing 2026-08-25 01:08:16 +09:00
jinhojang6 b7696b682b refactor(status.app): consolidate the canonical site origin into one constant 2026-08-25 01:08:16 +09:00
jinhojang6 db869e8d32 fix(status.app): stop emitting localhost URLs from production builds 2026-08-25 01:08:16 +09:00
Jules fd96d31c95 feat(wallet): sign EIP-712 typed data for dApps (#1301)
* refactor(wallet): drive the approval popup from the request type

A single `isSign` boolean set the title, the button label and the content
branch, so adding an approval type would have rendered it as "Connect dApp".
An exhaustive switch makes that a compile error instead.

* feat(wallet): sign EIP-712 typed data for dApps

`eth_signTypedData_v4` threw 4200. It now signs through the same per-origin
pinning and approval path as `personal_sign`.

Parameters are swapped relative to `personal_sign` -- address first, payload
second, per status-go `commands/sign.go`. The payload is parsed and validated
before the popup opens, `domain.chainId` included, so malformed input cannot
reach viem as an opaque -32603 after the user has already approved. The popup
renders it as hostile input, capped by depth, row count and value length.

* test(wallet): cover typed data signing

The swapped parameter order, malformed payloads refused before the popup, the
domain chain check across the three spellings dApps use, and the display caps.

* chore(wallet): add changeset

* fix(status.app): lint with eslint instead of next lint

`next lint` injects eslint-config-next, whose absolute-path `import/resolver`
entries replace the repo's own. Under pnpm's non-hoisted layout they resolve
from the config rather than the linted file, so an app-local dependency such as
`entities` reports as unresolved while root-hoisted ones do not.

The flat config already registers @next/next, so the Next rules still run.
`next lint` is deprecated and removed in Next 16.

* fix(wallet): render typed data rows from the signed type

Only the fields declared in types[primaryType] reach the EIP-712 hash.
Walking the raw message let a dApp pad it with unsigned keys until the
fields that are actually signed fell past the row cap, unseen. The
domain header had the same hole: a dApp-declared EIP712Domain decides
what the separator covers, so a name left out of it was displayed as
the dApp's identity without being signed.

* fix(wallet): bind the typed-data chain check to the signed domain

A dApp declaring its own EIP712Domain decides which domain fields reach
the separator, so a chainId present in domain but absent from that type
satisfied the chain check while binding the signature to no chain.

* test(wallet): cover the derived EIP712Domain chain check
2026-08-21 19:53:22 +09:00
jinhojang6 de1916d802 fix(status.app): improve mobile core web vitals 2026-08-07 00:17:07 +09:00
Jules ccef237691 feat(status.app): serve the reworked news feeds under /v2 (#1297)
* refactor(status.app): restore the shipped news feed rendering as v1

The clients in the wild parse what production serves today, so that build
is kept verbatim in its own module: unnamespaced `newsLink`, markup
stripped down to text, Ghost's escaping passed through. It imports nothing
but the XML parser, so a change to the reworked build cannot reach it.

`handleRssFeed` picks the build from a version that defaults to `v1`,
leaving the existing routes untouched.

* feat(status.app): serve the reworked news feeds under /v2

`/desktop-news/rss/v2` and `/mobile-news/rss/v2` carry the lists, the body
links, the escaping fixes and the namespaced call-to-action. The clients
move over once status-go reads the new elements; until then
`/desktop-news/rss` and `/mobile-news/rss` keep serving what they serve
today.
2026-08-07 00:16:49 +09:00
Jules 92f61f2f1e feat(status.app): keep body links in the desktop news feed (#1295)
Anchors were flattened to their label. The parser now carries them as
inline nodes, so a link in a paragraph or a list item reaches the desktop
client as `<a href>` with the href escaped, quotes included.

The mobile feed keeps the label alone -- plain text cannot carry a link --
and the call-to-action is still lifted out of the body. Validity is
unaffected: the whole body is escaped on its way into `description`.
2026-08-07 00:16:48 +09:00
Jules bb1e5f8f0d feat(status.app): render lists in the mobile and desktop news RSS feeds (#1293)
* chore(status.app): run unit tests with vitest

The workspace had test files but no test script, so turbo run test skipped them.

* feat(status.app): render lists in the news RSS feeds

Ghost HTML was split on </p> and stripped of every other tag, so list items
were concatenated into one run of text. Parse the markup into blocks instead
and emit <ul>/<ol>/<li>, keeping <br> as a single break.

Mobile now uses the same HTML formatting as desktop. The call-to-action link
is extracted structurally, so a link inside a list item can no longer replace
it and its label no longer leaks into the body.

* fix(status.app): escape Ghost values in the news RSS feeds

Ghost wraps titles and other text in CDATA, which the parser drops and the
builder rebuilds with entity processing off, so a bare & upstream was
re-served as invalid XML. Escape the values Ghost supplies, leaving existing
entities and the fields processItem generates alone.

* fix(status.app): keep the mobile news feed as plain text

The mobile client renders the description as plain text, so the HTML the
desktop feed emits would show up as literal markup. Render per feed: <ul>/<ol>
for desktop, text bullets for mobile.

* refactor(status.app): extract the news feed build from the RSS handler

Makes the pipeline a pure string transform, testable without the env the
handler pulls in, and drops the main/news ternaries from both paths.

* fix(status.app): escape the news feed channel description

`description` names both an item and a channel element, so skipping the
generated item fields channel-wide left Ghost's publication description
with a bare `&`, which invalidates the whole feed.

* fix(status.app): resolve Ghost's HTML entities in the news feeds

XML defines five entity names, so passing `&nbsp;` or `&copy;` through
cost the whole feed. Decoding is strict: the legacy HTML rules resolve
`&copy` without a semicolon and would corrupt a `?copy=1` query string.

* fix(status.app): escape the desktop news feed's markup

RSS 2.0 defines `description` as character data, so the markup is escaped
on its way into the XML tree rather than written as child elements of it.
status-go decodes the element with gofeed before handing it to the client,
which therefore receives the same markup as before. The mobile feed carries
no markup and stays untouched.

* fix(status.app): namespace the news feeds' call-to-action elements

RSS 2.0 rejects an extension element that carries no namespace, so
`newsLink` and `newsLinkLabel` move to `status:newsLink` and
`status:newsLinkLabel` under a namespace declared on `<rss>`.

gofeed routes a namespaced element to `item.Extensions` instead of
`item.Custom`, so status-go must read them from there before this ships.
2026-08-07 00:16:48 +09:00
jinhojang6 b73f5fdbc9 fix(status.app): keep metadata in document head 2026-07-31 19:59:54 +09:00
jinhojang6 fa3b484151 fix(status.app): render affected help article 2026-07-31 01:52:34 +09:00
jinhojang6 b5f937e21d fix(status.app): link remaining help articles 2026-07-31 01:52:34 +09:00
jinhojang6 bb7c373714 fix(status.app): collapse legacy help redirects 2026-07-31 01:42:50 +09:00
jinhojang6 4b0b4e6039 fix(status.app): handle empty legacy job ids 2026-07-31 01:42:34 +09:00
jinhojang6 a9affff2b9 fix(status.app): avoid legacy job redirect chains 2026-07-31 01:42:34 +09:00
Jules 3dcc27e805 fix(status.app): prevent desktop navbar overflow
* fix(status.app): prevent desktop navbar overflow

The top bar renders from 1150px but its full-text CTAs push the row past
the viewport until ~1315px, causing horizontal page overflow. Collapse the
download CTAs to icon-only below 1320px; full labels return above it.

* chore: add changeset

* fix(status.app): collapse floating navbar CTAs to icon-only

Mirror the top navbar: icon-only download CTAs below 1320px so the
floating scroll-up navbar can't overflow the viewport.

* fix(status.app): use native scroll listener for floating navbar

react-spring useScroll's rAF frameloop doesn't fire reliably under
Turbopack dev, so the overlay never appeared locally (worked in the
webpack prod build). Read window.scrollY via a plain scroll listener;
same detection logic.
2026-07-23 19:18:29 +09:00
jinhojang6 5f63ec0c77 Align blog search with content width 2026-07-23 00:58:52 +09:00
jinhojang6 04c214ffe7 fix(status.app): cap load-more at the search API result limit 2026-07-23 00:58:52 +09:00
jinhojang6 e67ca33bf8 fix(status.app): inline search index path so nft can trace it 2026-07-23 00:58:52 +09:00
jinhojang6 11708fcf0b fix(status.app): keep blog search index under public/ 2026-07-23 00:58:52 +09:00
jinhojang6 04c550d319 perf(status.app): move blog search to a server API route 2026-07-23 00:58:52 +09:00
jinhojang6 33ccb430bd Improve blog search performance 2026-07-23 00:58:52 +09:00
jinhojang6 757067cfd8 Polish blog search controls 2026-07-23 00:58:52 +09:00
jinhojang6 5b6a8e97c7 Add blog search 2026-07-23 00:58:52 +09:00
Jules 9337a39d2e fix(status.app): prevent keycard section overflow (#1282)
* fix(status.app): stop keycard section text column collapse

Drop w-full on the media wrapper; it pinned the flex basis to 100% and
starved the flex-1 text column to ~0. Fixes status.app and get.status.app
(shared HomePage). Regression from #1248.

* fix(status.app): stack keycard section below 1221px

* chore(status.app): add changeset
2026-07-22 16:01:57 +09:00
Jinho Jang 1173daa37a Fix robots.txt path matching (#1277)
* fix(status.app): narrow robots sharing path rules

* fix(status.app): anchor admin robots rules
2026-07-21 18:25:24 +09:00
KamandFelicio 00508329e6 Add SEO overrides for '/learn' route (#1213)
Co-authored-by: Felicio <felicio@users.noreply.github.com>
2026-07-21 17:59:53 +09:00
Jinho Jang fbe88fefb8 Add structured data for status.app pages (#1273)
* Add structured data for status.app pages

* fix(status.app): correct Article datePublished and heading excerpt in structured data

* fix(status.app): ignore code-fence comments as headings, recognize FAQs/Frequently Asked Questions

* test(status.app): add vitest config so structured-data tests actually run in CI

* refactor(status.app): share author-parsing between page and structured-data

* chore(status.app): remove test file and vitest infra from this PR

* fix(status.app): use valid structured data logo

* fix(ci): use develop for changeset checks

* fix(status.app): strip MDX comments from structured data
2026-07-16 22:04:37 +09:00
Jinho Jang 9df2aa3db0 fix(status.app): redirect renamed spec doc slugs to fix 404s (#1270) 2026-07-16 02:05:42 +09:00
Jinho Jang 337b88169d Noindex work-in-progress help docs (noindex audit) (#1269)
* fix(status.app): noindex placeholder help docs for noindex audit

* test(status.app): add coverage for isHelpDocWorkInProgress

* test(status.app): add vitest config so help-doc tests actually run in CI

* chore(status.app): remove test file and vitest infra from this PR
2026-07-16 01:49:33 +09:00
Jinho Jang ef2310f7e9 Fix blog crawler 5xx errors (#1268)
* Fix blog table rendering for crawler errors

* chore(status.app): add changeset for blog table 5xx fix

* fix(status.app): fix same table-crash bug in specsComponents, shared via renderTable

* chore(status.app): remove test file and vitest infra from this PR

* fix(status.app): preserve <th> row headers in table body cells (Copilot review)

* refactor(status.app): share content table rendering
2026-07-10 21:06:51 +09:00
Felicio 3f3b6f3794 fix layout for statically exported apps/ (#1248) 2026-07-08 19:22:55 +09:00
Felicio e203d9115b fix(get.status.app): clean up remaining crypto source content (#1244) 2026-07-03 21:13:26 +09:00
Jinho JangandFelicio 320438c5b4 fix(get.status.app): remove crypto source content (#1242)
Co-authored-by: Felicio <felicio@users.noreply.github.com>
2026-07-01 22:39:05 +09:00
sunleos 2beed23099 Update terms-of-use.md - fixes (#1241) 2026-07-01 15:46:13 +09:00
Felicio 9f0fd7d9dd fix(status.app): remove cloaking signals on get.status.app (#1238) 2026-06-26 23:34:52 +09:00
Felicio 685e3d0406 Hide removed get.status.app sections (#1237) 2026-06-26 14:04:33 +09:00
Jinho Jang 40f0efcec9 chore(status.app): comment out org chart section on team page (#1233)
* chore(status.app): comment out org chart section on team page

* chore(status.app): add changeset for org chart
2026-06-23 05:19:26 +09:00
9c2974b2fc chore(status.app): remove beta warning admonition on help pages
* chore(status.app): remove beta warning admonition on help pages

* chore: add changeset

---------

Co-authored-by: JulesFILIOT <dev@julesfiliot.com>
Co-authored-by: Jules <78474837+JulesFiliot@users.noreply.github.com>
2026-06-23 00:09:20 +09:00
Jinho Jang a407f80445 fix(sitemap): exclude blog tag pages from status.app sitemap (#1223)
* fix(sitemap): exclude blog tag pages from status.app sitemap

* fix(sitemap): add changeset to exclude blog tag pages from sitemap
2026-06-16 00:48:23 +09:00
Jinho Jang 9585bda6f7 Fix mobile overflow for blog tables (#1222) 2026-06-12 21:11:41 +09:00
Felicio d624890f45 self-host apps/status.app (#1199) 2026-06-12 13:52:47 +09:00
Jinho Jang 20985dc881 fix(blog): style Ghost post tables and blockquotes (#1218)
* fix(blog): style Ghost post tables and reduce blockquote size

* chore: add changeset

* fix(blog): make blockquote left border more visible

* refactor(blog): reuse Table design system component for blog tables

* fix(table): adjust width properties for better responsiveness
2026-06-12 12:47:39 +09:00