Skip to content

feat: create announcements banner#617

Open
araujogui wants to merge 13 commits intomainfrom
feat/banners
Open

feat: create announcements banner#617
araujogui wants to merge 13 commits intomainfrom
feat/banners

Conversation

@araujogui
Copy link
Member

Description

Create announcements banner component

Validation

image

Related Issues

Fixes #327

Check List

  • I have read the Contributing Guidelines and made commit messages that follow the guideline.
  • I have run node --run test and all tests passed.
  • I have check code formatting with node --run format & node --run lint.
  • I've covered new added functionality with unit tests if necessary.

@araujogui araujogui requested a review from a team as a code owner February 20, 2026 19:56
Copilot AI review requested due to automatic review settings February 20, 2026 19:56
@vercel
Copy link

vercel bot commented Feb 20, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
api-docs-tooling Ready Ready Preview Mar 25, 2026 11:03pm

Request Review

@codecov
Copy link

codecov bot commented Feb 20, 2026

Codecov Report

❌ Patch coverage is 11.11111% with 16 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.34%. Comparing base (d121f54) to head (b266e22).

Files with missing lines Patch % Lines
src/generators/jsx-ast/utils/buildContent.mjs 11.11% 8 Missing ⚠️
src/generators/web/utils/generate.mjs 0.00% 7 Missing ⚠️
src/generators/web/utils/processing.mjs 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #617      +/-   ##
==========================================
- Coverage   75.40%   75.34%   -0.06%     
==========================================
  Files         148      148              
  Lines       13586    13598      +12     
  Branches     1025     1025              
==========================================
+ Hits        10245    10246       +1     
- Misses       3336     3347      +11     
  Partials        5        5              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions
Copy link

github-actions bot commented Feb 20, 2026

api-links Generator

apilinks.json
Expected values to be strictly deep-equal:
+ actual - expected
... Skipped lines

  {
    'Agent.defaultMaxSockets': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_agent.js#L227',
    'Buffer.alloc': 'https://github.com/nodejs/node/blob/HEAD/lib/buffer.js#L432',
    'Buffer.allocUnsafe': 'https://github.com/nodejs/node/blob/HEAD/lib/buffer.js#L446',
    'Buffer.allocUnsafeSlow': 'https://github.com/nodejs/node/blob/HEAD/lib/buffer.js#L458',
...
    'agent.addRequest': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_agent.js#L292',
+   'agent.createConnection': 'https://github.com/nodejs/node/blob/HEAD/lib/https.js#L326',
-   'agent.createConnection': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_agent.js#L231',
    'agent.createSocket': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_agent.js#L363',
    'agent.destroy': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_agent.js#L595',
+   'agent.getName': 'https://github.com/nodejs/node/blob/HEAD/lib/https.js#L484',
-   'agent.getName': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_agent.js#L261',
    'agent.keepSocketAlive': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_agent.js#L552',
    'agent.removeSocket': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_agent.js#L491',
    'agent.reuseSocket': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_agent.js#L588',
    'assert.assert': 'https://github.com/nodejs/node/blob/HEAD/lib/assert.js#L185',
    'asyncResource.asyncId': 'https://github.com/nodejs/node/blob/HEAD/lib/async_hooks.js#L242',
...
    'server.address': 'https://github.com/nodejs/node/blob/HEAD/lib/net.js#L2289',
+   'server.close': 'https://github.com/nodejs/node/blob/HEAD/lib/net.js#L2422',
+   'server.closeAllConnections': 'https://github.com/nodejs/node/blob/HEAD/lib/https.js#L120',
+   'server.closeIdleConnections': 'https://github.com/nodejs/node/blob/HEAD/lib/https.js#L122',
-   'server.close': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_server.js#L614',
-   'server.closeAllConnections': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_server.js#L624',
-   'server.closeIdleConnections': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_server.js#L636',
    'server.getConnections': 'https://github.com/nodejs/node/blob/HEAD/lib/net.js#L2384',
    'server.listen': 'https://github.com/nodejs/node/blob/HEAD/lib/net.js#L2106',
    'server.ref': 'https://github.com/nodejs/node/blob/HEAD/lib/net.js#L2527',
+   'server.setTimeout': 'https://github.com/nodejs/node/blob/HEAD/lib/https.js#L124',
-   'server.setTimeout': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_server.js#L652',
    'server.unref': 'https://github.com/nodejs/node/blob/HEAD/lib/net.js#L2536',
+   'server[SymbolAsyncDispose]': 'https://github.com/nodejs/node/blob/HEAD/lib/net.js#L2462',
+   'server[undefined]': 'https://github.com/nodejs/node/blob/HEAD/lib/net.js#L2491',
-   'server[SymbolAsyncDispose]': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_server.js#L620',
-   'server[undefined]': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_server.js#L659',
    'serverresponse._finish': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_server.js#L246',
    'serverresponse._implicitHeader': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_server.js#L360',
    'serverresponse.assignSocket': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_server.js#L296',
    'serverresponse.detachSocket': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_server.js#L307',
    'serverresponse.statusCode': 'https://github.com/nodejs/node/blob/HEAD/lib/_http_server.js#L269',

orama-db Generator

File Base Head Diff
orama-db.json 8.05 MB 8.05 MB -2.00 B (-0.00%)

web Generator

File Base Head Diff
quic.html 357.91 KB 361.17 KB +3.26 KB (+0.91%)
http.html 737.31 KB 740.20 KB +2.89 KB (+0.39%)
process.html 674.86 KB 677.34 KB +2.48 KB (+0.37%)
styles.css 137.01 KB 139.42 KB +2.41 KB (+1.76%)
perf_hooks.html 380.10 KB 382.32 KB +2.22 KB (+0.58%)
crypto.html 1.03 MB 1.03 MB +1.51 KB (+0.14%)
net.html 381.99 KB 383.32 KB +1.33 KB (+0.35%)
worker_threads.html 364.89 KB 366.05 KB +1.16 KB (+0.32%)
errors.html 460.26 KB 461.41 KB +1.14 KB (+0.25%)
test.html 739.86 KB 740.89 KB +1.03 KB (+0.14%)
tls.html 373.83 KB 374.80 KB +989.00 B (+0.26%)
buffer.html 906.59 KB 907.55 KB +979.00 B (+0.11%)
util.html 692.59 KB 693.51 KB +943.00 B (+0.13%)
child_process.html 381.80 KB 382.72 KB +941.00 B (+0.24%)
vm.html 370.83 KB 371.71 KB +905.00 B (+0.24%)
cluster.html 195.66 KB 196.52 KB +879.00 B (+0.44%)
globals.html 229.63 KB 230.47 KB +865.00 B (+0.37%)
sqlite.html 268.43 KB 269.24 KB +829.00 B (+0.30%)
modules.html 178.06 KB 178.87 KB +827.00 B (+0.45%)
events.html 455.26 KB 456.00 KB +759.00 B (+0.16%)
inspector.html 170.94 KB 171.68 KB +751.00 B (+0.43%)
webcrypto.html 506.53 KB 507.27 KB +751.00 B (+0.14%)
https.html 149.75 KB 150.45 KB +715.00 B (+0.47%)
esm.html 154.69 KB 155.36 KB +677.00 B (+0.43%)
tty.html 94.76 KB 95.42 KB +675.00 B (+0.70%)
path.html 138.85 KB 139.48 KB +645.00 B (+0.45%)
os.html 142.36 KB 142.95 KB +605.00 B (+0.42%)
punycode.html 62.66 KB 63.21 KB +565.00 B (+0.88%)
zlib.html 290.47 KB 291.02 KB +563.00 B (+0.19%)
fs.html 1.40 MB 1.40 MB +561.00 B (+0.04%)
http2.html 769.55 KB 770.10 KB +561.00 B (+0.07%)
module.html 326.60 KB 327.15 KB +561.00 B (+0.17%)
readline.html 251.98 KB 252.53 KB +561.00 B (+0.22%)
environment_variables.html 43.51 KB 44.02 KB +525.00 B (+1.18%)
repl.html 182.97 KB 183.48 KB +525.00 B (+0.28%)
async_context.html 163.14 KB 163.66 KB +523.00 B (+0.31%)
async_hooks.html 159.29 KB 159.80 KB +523.00 B (+0.32%)
domain.html 104.61 KB 105.12 KB +523.00 B (+0.49%)
wasi.html 69.07 KB 69.58 KB +523.00 B (+0.74%)
addons.html 262.06 KB 262.54 KB +485.00 B (+0.18%)
assert.html 330.39 KB 330.87 KB +485.00 B (+0.14%)
cli.html 490.32 KB 490.79 KB +485.00 B (+0.10%)
console.html 146.51 KB 146.98 KB +485.00 B (+0.32%)
debugger.html 53.73 KB 54.20 KB +485.00 B (+0.88%)
deprecations.html 501.80 KB 502.27 KB +485.00 B (+0.09%)
dgram.html 194.23 KB 194.71 KB +485.00 B (+0.24%)
diagnostics_channel.html 243.47 KB 243.95 KB +485.00 B (+0.19%)
dns.html 296.23 KB 296.71 KB +485.00 B (+0.16%)
documentation.html 37.55 KB 38.02 KB +485.00 B (+1.26%)
embedding.html 58.93 KB 59.40 KB +485.00 B (+0.80%)
index.html 35.63 KB 36.10 KB +485.00 B (+1.33%)
intl.html 57.64 KB 58.12 KB +485.00 B (+0.82%)
n-api.html 806.76 KB 807.23 KB +485.00 B (+0.06%)
packages.html 154.19 KB 154.67 KB +485.00 B (+0.31%)
permissions.html 54.64 KB 55.12 KB +485.00 B (+0.87%)
querystring.html 63.47 KB 63.95 KB +485.00 B (+0.75%)
report.html 175.42 KB 175.89 KB +485.00 B (+0.27%)
single-executable-applications.html 106.51 KB 106.99 KB +485.00 B (+0.44%)
stream.html 858.65 KB 859.12 KB +485.00 B (+0.06%)
string_decoder.html 54.95 KB 55.42 KB +485.00 B (+0.86%)
synopsis.html 42.17 KB 42.65 KB +485.00 B (+1.12%)
timers.html 133.19 KB 133.67 KB +485.00 B (+0.36%)
tracing.html 83.69 KB 84.17 KB +485.00 B (+0.57%)
typescript.html 52.97 KB 53.45 KB +485.00 B (+0.89%)
url.html 348.20 KB 348.67 KB +485.00 B (+0.14%)
v8.html 321.20 KB 321.67 KB +485.00 B (+0.15%)
webstreams.html 356.57 KB 357.04 KB +485.00 B (+0.13%)
addons.js 292.87 KB 292.95 KB +86.00 B (+0.03%)
assert.js 453.86 KB 453.94 KB +86.00 B (+0.02%)
async_context.js 185.96 KB 186.04 KB +86.00 B (+0.05%)
async_hooks.js 195.27 KB 195.35 KB +86.00 B (+0.04%)
buffer.js 1.08 MB 1.08 MB +86.00 B (+0.01%)
child_process.js 462.99 KB 463.08 KB +86.00 B (+0.02%)
cli.js 300.12 KB 300.21 KB +86.00 B (+0.03%)
cluster.js 194.50 KB 194.58 KB +86.00 B (+0.04%)
console.js 105.96 KB 106.04 KB +86.00 B (+0.08%)
crypto.js 1.13 MB 1.13 MB +86.00 B (+0.01%)
debugger.js 29.73 KB 29.81 KB +86.00 B (+0.28%)
deprecations.js 287.36 KB 287.45 KB +86.00 B (+0.03%)
dgram.js 170.00 KB 170.08 KB +86.00 B (+0.05%)
diagnostics_channel.js 234.94 KB 235.03 KB +86.00 B (+0.04%)
dns.js 263.28 KB 263.36 KB +86.00 B (+0.03%)
documentation.js 9.06 KB 9.15 KB +86.00 B (+0.93%)
domain.js 89.67 KB 89.76 KB +86.00 B (+0.09%)
embedding.js 36.76 KB 36.84 KB +86.00 B (+0.23%)
environment_variables.js 14.52 KB 14.60 KB +86.00 B (+0.58%)
errors.js 350.91 KB 350.99 KB +86.00 B (+0.02%)
esm.js 135.01 KB 135.09 KB +86.00 B (+0.06%)
events.js 544.06 KB 544.15 KB +86.00 B (+0.02%)
fs.js 1.17 MB 1.17 MB +86.00 B (+0.01%)
globals.js 126.90 KB 126.99 KB +86.00 B (+0.07%)
http.js 672.17 KB 672.25 KB +86.00 B (+0.01%)
http2.js 801.07 KB 801.16 KB +86.00 B (+0.01%)
https.js 159.33 KB 159.42 KB +86.00 B (+0.05%)
index.js 9.60 KB 9.68 KB +86.00 B (+0.87%)
inspector.js 118.70 KB 118.78 KB +86.00 B (+0.07%)
intl.js 35.98 KB 36.06 KB +86.00 B (+0.23%)
module.js 334.78 KB 334.87 KB +86.00 B (+0.03%)
modules.js 148.25 KB 148.33 KB +86.00 B (+0.06%)
n-api.js 710.34 KB 710.42 KB +86.00 B (+0.01%)
net.js 276.21 KB 276.30 KB +86.00 B (+0.03%)
os.js 104.68 KB 104.77 KB +86.00 B (+0.08%)
packages.js 122.27 KB 122.35 KB +86.00 B (+0.07%)
path.js 96.12 KB 96.20 KB +86.00 B (+0.09%)
perf_hooks.js 359.58 KB 359.67 KB +86.00 B (+0.02%)
permissions.js 28.36 KB 28.45 KB +86.00 B (+0.30%)
process.js 704.01 KB 704.10 KB +86.00 B (+0.01%)
punycode.js 27.44 KB 27.53 KB +86.00 B (+0.31%)
querystring.js 30.36 KB 30.45 KB +86.00 B (+0.28%)
quic.js 153.08 KB 153.17 KB +86.00 B (+0.05%)
readline.js 221.74 KB 221.82 KB +86.00 B (+0.04%)
repl.js 209.15 KB 209.24 KB +86.00 B (+0.04%)
report.js 188.07 KB 188.15 KB +86.00 B (+0.04%)
single-executable-applications.js 83.10 KB 83.19 KB +86.00 B (+0.10%)
sqlite.js 228.89 KB 228.98 KB +86.00 B (+0.04%)
stream.js 851.50 KB 851.58 KB +86.00 B (+0.01%)
string_decoder.js 30.88 KB 30.96 KB +86.00 B (+0.27%)
synopsis.js 15.49 KB 15.58 KB +86.00 B (+0.54%)
test.js 851.49 KB 851.58 KB +86.00 B (+0.01%)
timers.js 97.49 KB 97.57 KB +86.00 B (+0.09%)
tls.js 313.18 KB 313.26 KB +86.00 B (+0.03%)
tracing.js 76.69 KB 76.78 KB +86.00 B (+0.11%)
tty.js 47.04 KB 47.13 KB +86.00 B (+0.18%)
typescript.js 24.14 KB 24.23 KB +86.00 B (+0.35%)
url.js 335.41 KB 335.49 KB +86.00 B (+0.03%)
util.js 741.14 KB 741.22 KB +86.00 B (+0.01%)
v8.js 330.33 KB 330.42 KB +86.00 B (+0.03%)
vm.js 436.93 KB 437.01 KB +86.00 B (+0.02%)
wasi.js 41.50 KB 41.58 KB +86.00 B (+0.20%)
webcrypto.js 381.09 KB 381.17 KB +86.00 B (+0.02%)
webstreams.js 283.28 KB 283.36 KB +86.00 B (+0.03%)
worker_threads.js 394.13 KB 394.21 KB +86.00 B (+0.02%)
zlib.js 312.21 KB 312.29 KB +86.00 B (+0.03%)

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements an announcement banner component that fetches configuration from a remote JSON endpoint to display global and version-specific banners on the API documentation pages. The banners support date-based activation/deactivation and can include links to relevant resources.

Changes:

  • Added AnnouncementBanner component that asynchronously fetches and displays banners from a remote config
  • Implemented isBannerActive utility function to filter banners based on date ranges
  • Added versionMajor and remoteConfig fields to static data passed from server to client

Reviewed changes

Copilot reviewed 7 out of 9 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/generators/web/index.mjs Adds remote config URL to web generator default configuration
src/generators/web/types.d.ts Adds remoteConfig type definition for the web generator
src/generators/web/utils/data.mjs Extracts version major and remote config URL from server config to client static data
src/generators/web/constants.mjs Registers AnnouncementBanner component in JSX imports map
src/generators/jsx-ast/utils/buildContent.mjs Adds AnnouncementBanner to document layout above navigation bar
src/generators/web/ui/utils/banner.mjs Implements date range checking logic for banner activation
src/generators/web/ui/utils/__tests__/banner.test.mjs Comprehensive tests for banner date range logic
src/generators/web/ui/components/AnnouncementBanner/types.d.ts Type definitions for banner entries and remote config structure
src/generators/web/ui/components/AnnouncementBanner/index.jsx Main component that fetches config and renders active banners

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

<div>
{banners.map(banner => (
<Banner key={banner.link} type={banner.type}>
{banner.link ? <a href={banner.link}>{banner.text}</a> : banner.text}
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

External URLs from the remote config are used directly in href attributes without validation. While React/Preact provides some protection against javascript: protocol URLs, there's still a potential security risk if the remote config source is compromised. Consider validating that banner.link uses an approved protocol (https://) or implementing an allowlist of acceptable domains to ensure only trusted URLs are rendered. This is especially important since the config is fetched from an external source.

Copilot uses AI. Check for mistakes.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@avivkeller @ovflowd what do you think? is this necessary? We don't do this on nodejs website

@ovflowd
Copy link
Member

ovflowd commented Feb 21, 2026

@araujogui please be aware this must 100% be a client-side only component. Since the value of this comes from being able to fetch this at page load, as docs are built only once for each version.

@ovflowd
Copy link
Member

ovflowd commented Feb 21, 2026

(this also means that this spec cannot ever change or needs to be forever retroactively compatible)

@avivkeller
Copy link
Member

please be aware this must 100% be a client-side only component

It is

@araujogui
Copy link
Member Author

araujogui commented Feb 21, 2026

@araujogui please be aware this must 100% be a client-side only component. Since the value of this comes from being able to fetch this at page load, as docs are built only once for each version.

uh, that also means we can't change the config url, so we should already create the config file on nodejs/node?

@ovflowd
Copy link
Member

ovflowd commented Feb 21, 2026

@araujogui please be aware this must 100% be a client-side only component. Since the value of this comes from being able to fetch this at page load, as docs are built only once for each version.

uh, that also means we can't change the config url, so we should already create the config file on nodejs/node?

Yeah... So we need to be very careful here 😓

@araujogui
Copy link
Member Author

araujogui commented Feb 25, 2026

@araujogui please be aware this must 100% be a client-side only component. Since the value of this comes from being able to fetch this at page load, as docs are built only once for each version.

uh, that also means we can't change the config url, so we should already create the config file on nodejs/node?

Yeah... So we need to be very careful here 😓

We already have a site.json on website repo, having another config file on nodejs/node looks like duplication?

@ovflowd
Copy link
Member

ovflowd commented Feb 25, 2026

@araujogui please be aware this must 100% be a client-side only component. Since the value of this comes from being able to fetch this at page load, as docs are built only once for each version.

uh, that also means we can't change the config url, so we should already create the config file on nodejs/node?

Yeah... So we need to be very careful here 😓

We already have a site.json on website repo, having another config file on nodejs/node looks like duplication?

We can use site.json, but note that it is not publicly available, the link would either need to be through raw.githubusercontent.com or we'd need to move the file to be publicly available.

@araujogui
Copy link
Member Author

@araujogui please be aware this must 100% be a client-side only component. Since the value of this comes from being able to fetch this at page load, as docs are built only once for each version.

uh, that also means we can't change the config url, so we should already create the config file on nodejs/node?

Yeah... So we need to be very careful here 😓

We already have a site.json on website repo, having another config file on nodejs/node looks like duplication?

We can use site.json, but note that it is not publicly available, the link would either need to be through raw.githubusercontent.com or we'd need to move the file to be publicly available.

I think raw.githubusercontent.com is good enough

@ovflowd
Copy link
Member

ovflowd commented Feb 26, 2026

@araujogui please be aware this must 100% be a client-side only component. Since the value of this comes from being able to fetch this at page load, as docs are built only once for each version.

uh, that also means we can't change the config url, so we should already create the config file on nodejs/node?

Yeah... So we need to be very careful here 😓

We already have a site.json on website repo, having another config file on nodejs/node looks like duplication?

We can use site.json, but note that it is not publicly available, the link would either need to be through raw.githubusercontent.com or we'd need to move the file to be publicly available.

I think raw.githubusercontent.com is good enough

IDK about that...

@MattIPv4
Copy link
Member

I'd be fine with using raw.githubusercontent.com at build time (like we do via nodevu on the site), but I don't think we should be reliant on hitting it client-side every time someone loads a page on the site, that feels like abuse of GitHub's service. Can we have a JSON file accessible via the site, or an API endpiont?

@ovflowd
Copy link
Member

ovflowd commented Feb 26, 2026

I'd be fine with using raw.githubusercontent.com at build time (like we do via nodevu on the site), but I don't think we should be reliant on hitting it client-side every time someone loads a page on the site, that feels like abuse of GitHub's service. Can we have a JSON file accessible via the site, or an API endpiont?

We won't be loading this at build-time, cause it is supposed to be a client-side only, so it would hit indeed on every page load. I don't think raw.githubusercontent.com has cache headers so it would not be good.

@araujogui
Copy link
Member Author

I'd be fine with using raw.githubusercontent.com at build time (like we do via nodevu on the site), but I don't think we should be reliant on hitting it client-side every time someone loads a page on the site, that feels like abuse of GitHub's service. Can we have a JSON file accessible via the site, or an API endpiont?

We won't be loading this at build-time, cause it is supposed to be a client-side only, so it would hit indeed on every page load. I don't think raw.githubusercontent.com has cache headers so it would not be good.

Okay, maybe we could expose site.json in an endpoint of the website

Copy link
Member

@ovflowd ovflowd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's put a block on this for now as this needs to be done thoughtfully

@canerakdas
Copy link
Member

I think there's a design/UX problem we need to solve here. Since we fetch the current announcements via a client-side request, they arrive later and naturally cause cumulative layout shift

Screen.Recording.2026-03-21.at.14.23.22.mov

For a better experience, even though I'm not a big fan of floating elements, we might need something like a toast component:
https://www.radix-ui.com/primitives/docs/components/toast


I don't think this is something that should block the PR, but it would be great to discuss alternative ideas if there are any that could provide a better experience cc @nodejs/nodejs-website

@ovflowd
Copy link
Member

ovflowd commented Mar 21, 2026

I think there's a design/UX problem we need to solve here. Since we fetch the current announcements via a client-side request, they arrive later and naturally cause cumulative layout shift

Screen.Recording.2026-03-21.at.14.23.22.mov
For a better experience, even though I'm not a big fan of floating elements, we might need something like a toast component: radix-ui.com/primitives/docs/components/toast

I don't think this is something that should block the PR, but it would be great to discuss alternative ideas if there are any that could provide a better experience cc @nodejs/nodejs-website

I get where you're coming from, I think what we can do here is add a delay on it showing and having a smooth transition (slide down) via CSS. Because I'm not sure Toasts would be better here for acessibility reasons.

@canerakdas
Copy link
Member

I get where you're coming from, I think what we can do here is add a delay on it showing and having a smooth transition (slide down) via CSS. Because I'm not sure Toasts would be better here for acessibility reasons.

Looks like we've already found a better solution 😄

@ovflowd
Copy link
Member

ovflowd commented Mar 25, 2026

@araujogui can you rebase?

}

const res = await fetch(remoteConfig, {
signal: AbortSignal.timeout(2500),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need a signal here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to avoid hanging connections if remote is down

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement real-time (on-load) updates to API docs live-environment

6 participants