You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
feat(components): add Carbon Ads top bar and sidebar - #8489
Top bar (zone CWBI623E): a dismissible banner above the page content. Closing it hides it for the rest of the session without requesting another ad.
Sidebar card (zone CWBI6K77): shown at the bottom of the docs sidebar, and only requested at md and up, where the sidebar is visible.
Ads are fetched from Carbon's JSON API. A view beacon fires once at least 50% of the ad has been visible for one continuous second.
Each page change fetches a fresh ad. The homepage, the 404 page, and printable pages render no ad markup and make no requests.
Advertiser colors are applied through custom properties, including the dark-theme palette. The stylesheet is global CSS, not a CSS module, so those property names are not renamed.
Things to check before merging
Impression counting. Requests are sent without ignore=yes, so local and preview builds count impressions. Carbon's nodejs.org integration gates this behind a production build flag. Decide whether this site should do the same.
Zone IDs and approval. The zone IDs and the creatives need Carbon's sign-off before this ships.
Testing
Checks on the changed files: ESLint, Prettier, cspell, and the Jest Page test all pass.
The dev server was checked in the browser on /concepts/ in light and dark themes, at a phone width, after dismissing the banner, and after navigating to /guides/.
Not run: the full Jest suite, the production build, and the link checker.
Show Carbon Ads on documentation pages: a dismissible banner above the page content and a card at the bottom of the sidebar (desktop only). Ads are fetched from Carbon's JSON API, and views are only beaconed once at least half of the ad has been visible for a second.
Assisted-by: Cursor
The change adds a Carbon ad hook that fetches ads, maps ad colors, and tracks views. It adds top-bar and sidebar ad components with shared styles and session-based dismissal for the top-bar ad. The page and sidebar layouts render these components except on printable paths. The ESLint configuration and spell-check dictionary also include entries for the new code and ad fields.
Pre-merge checks: 5
Check name
Status
Explanation
Description Check
Check skipped - CodeRabbit’s high-level summary is enabled.
Title check
The title clearly summarizes the main change: adding Carbon Ads to the top bar and sidebar.
Docstring Coverage
Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentati…
Linked Issues check
Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check
Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage
Explanation
Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 6 functions across 6 files. (2 skipped: 2 unsupported.)
Finishing Touches
Generate docstrings
Commit to this branch
Create a new PR
Generate unit tests (beta)
Commit to this branch
Create a new PR
Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Warning
Tools execution failed with the following error:
Failed to run tools: 13 INTERNAL: Received RST_STREAM with code 2 (Internal server error)
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.
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
Additional comments: 1
src/components/CarbonAd/useCarbonAd.mjs: 1
37-61: Trivial · Nitpick
Unverified finding
Verification ran but could not confirm this finding. It is shown for review, not as a verified issue.
Gap: the one-per-mount fetch also fires on dev and preview builds.
The hook sends the ad request and the view beacon on every build, including local and preview builds. Those builds count impressions. The PR description lists this as an open decision. Decide before merge whether to gate the hook on a production-only flag, for example a webpack DefinePlugin constant.
Review info
Run configuration
Source mode: Auto
Repository: Unavailable
Branch: Unavailable
File: No configuration file from this repository applied
Commit: Unavailable
Layers: Organization UI
Review profile: CHILL
Plan: Advanced
Run ID: 7d2d8001-3c34-4df9-9ca1-4fd10e632ec6
Commits
Reviewing files that changed from the base of the PR and between 9cfb83c and 07a764f.
Files selected for processing: 8
cspell.json
eslint.config.mjs
src/components/CarbonAd/SideBar.jsx
src/components/CarbonAd/TopBar.jsx
src/components/CarbonAd/carbon-ad.css
src/components/CarbonAd/useCarbonAd.mjs
src/components/Page/Page.jsx
src/components/Sidebar/Sidebar.jsx
Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.
The reason will be displayed to describe this comment to others. Learn more.
Minor · Functional Correctness · Quick win
Supported by static analysis
Script executed:
sed -n '1,110p' src/components/CarbonAd/TopBar.jsx
sed -n '1,115p' src/components/CarbonAd/carbon-ad.css
sed -n '110,140p' src/components/Page/Page.jsx
On a phone-width documentation page, useCarbonAd("CWBI623E") can request and display the banner because it has no viewport guard. Gate the request below 768px and hide the banner when the viewport narrows.
The reason will be displayed to describe this comment to others. Learn more.
Minor · Stability & Availability · Quick win
Guard the sessionStorage read.
Accessing globalThis.sessionStorage can throw a SecurityError when the browser blocks storage. The throw happens during render and can break the whole Page. Wrap the read in try/catch and default to false.
Proposed fix
--- "a/src/components/CarbonAd/TopBar.jsx"+++ "b/src/components/CarbonAd/TopBar.jsx"@@ -60,9 +60,13 @@
export default function TopBarAd() {
// There is no storage while rendering on the server.
- const [dismissed, setDismissed] = useState(- () => globalThis.sessionStorage?.getItem(DISMISSED_KEY) === "true",- );+ const [dismissed, setDismissed] = useState(() => {+ try {+ return globalThis.sessionStorage?.getItem(DISMISSED_KEY) === "true";+ } catch {+ return false;+ }+ });
if (dismissed) {
return null;
Based on learnings: flag storage calls only when nothing handles thrown exceptions.
Committable suggestion
IMPORTANT
Review the replacement and indentation, then test before committing.
The reason will be displayed to describe this comment to others. Learn more.
Minor · Stability & Availability · Quick win
Handle a storage failure in the close handler.
sessionStorage.setItem throws when storage is blocked or full (for example, SecurityError or QuotaExceededError). The throw happens inside the click handler, so setDismissed(true) never runs. The banner then cannot be closed. The read at Line 64 is unguarded as well. Reading sessionStorage can throw when storage access is blocked.
Wrap both accesses in try/catch. Always call setDismissed(true).
Proposed fix
--- "a/src/components/CarbonAd/TopBar.jsx"+++ "b/src/components/CarbonAd/TopBar.jsx"@@ -70,10 +70,14 @@
return (
<Ad
onClose={() => {
- sessionStorage.setItem(DISMISSED_KEY, "true");+ try {+ sessionStorage.setItem(DISMISSED_KEY, "true");+ } catch {+ // Storage is unavailable. Dismiss for this mount only.+ }
setDismissed(true);
}}
/>
);
}
Based on learnings: flag storage calls only when nothing handles thrown exceptions.
Committable suggestion
IMPORTANT
Review the replacement and indentation, then test before committing.
Suggested change
sessionStorage.setItem(DISMISSED_KEY,"true");
try{
sessionStorage.setItem(DISMISSED_KEY,"true");
}catch{
// Storage is unavailable. Dismiss for this mount only.
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Duplicate comments: 1
src/components/CarbonAd/TopBar.jsx: 1
63-65: Minor · Stability & Availability · Quick win
Handle sessionStorage failures.
sessionStorage access can throw SecurityError when storage is blocked. It can throw QuotaExceededError on write. The read at Line 64 runs during render and can break Page. The write at Line 74 throws before setDismissed(true) runs, so the user cannot close the banner. Wrap both calls in try/catch. Always call setDismissed(true).
File: No configuration file from this repository applied
Commit: Unavailable
Layers: Organization UI
Review profile: CHILL
Plan: Advanced
Run ID: 3974126b-84ab-4eb8-b88a-eceff2ec82cb
Commits
Reviewing files that changed from the base of the PR and between 9cfb83c and 7b4b2a4.
Files selected for processing: 8
cspell.json
eslint.config.mjs
src/components/CarbonAd/SideBar.jsx
src/components/CarbonAd/TopBar.jsx
src/components/CarbonAd/carbon-ad.css
src/components/CarbonAd/useCarbonAd.mjs
src/components/Page/Page.jsx
src/components/Sidebar/Sidebar.jsx
Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 6 remain after this review.
The reason will be displayed to describe this comment to others. Learn more.
Minor · Functional Correctness · Quick win
Restrict the top-bar ad to md and wider.
useCarbonAd("CWBI623E") has no media argument. Phone-width visitors therefore request and see the banner. The PR states that ads are requested only at md and above. Pass "(min-width: 768px)" as the second argument.
This also removes the phone-width request and impression. A viewport that narrows after the fetch still shows the banner. Hide it with a CSS max-md:hidden class if that matters.
Proposed fix
--- "a/src/components/CarbonAd/TopBar.jsx"+++ "b/src/components/CarbonAd/TopBar.jsx"@@ -11,7 +11,7 @@
* rest of the visit and does not request another ad.
*/
function Ad({ onClose }) {
- const { ad, ref } = useCarbonAd("CWBI623E");+ const { ad, ref } = useCarbonAd("CWBI623E", "(min-width: 768px)");
if (!ad) {
return null;
Committable suggestion
IMPORTANT
Review the replacement and indentation, then test before committing.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds Carbon Ads to the documentation pages, ported from webpack/webpack-doc-kit#294, with the visual styling from nodejs/nodejs.org#9250.
CWBI623E): a dismissible banner above the page content. Closing it hides it for the rest of the session without requesting another ad.CWBI6K77): shown at the bottom of the docs sidebar, and only requested atmdand up, where the sidebar is visible.Things to check before merging
ignore=yes, so local and preview builds count impressions. Carbon's nodejs.org integration gates this behind a production build flag. Decide whether this site should do the same.Testing
Pagetest all pass./concepts/in light and dark themes, at a phone width, after dismissing the banner, and after navigating to/guides/.Assisted-by: Cursor
Made with Cursor
Summary by CodeRabbit