Skip to content

fix: stack sidebar footer as a row in production builds - #180

Merged
rsbh merged 1 commit into
mainfrom
fix/sidebar-footer-row-layout
Sep 1, 2026
Merged

fix: stack sidebar footer as a row in production builds#180
rsbh merged 1 commit into
mainfrom
fix/sidebar-footer-row-layout

Conversation

@rsbh

@rsbh rsbh commented Aug 31, 2026

Copy link
Copy Markdown
Member

The bug

In the default theme, the sidebar footer's version switcher and links menu render on separate lines instead of opposite ends of one row. Visible on built sites only — example.

Why it passed review

It doesn't reproduce in dev. Same code, same machine:

flex-direction align-items justify-content
dev:examples:versioned row center space-between
build:examples:basic + start column stretch flex-start

.sidebarFooter declares the row layout, but Apsara's Sidebar.Footer renders a Flex with direction='column'. Both are single-class selectors — equal specificity (0,1,0) — so stylesheet order decides.

Vite injects each CSS module as its own <style> tag in dev, where the theme's module lands after Apsara's and wins. The production bundle concatenates in chunk-graph order, putting Apsara's flex-module utilities after the theme module, flipping the tie:

._sidebarFooter_…                 rule  21   flex-direction: row
.flex-module_direction-column__…  rule 365   flex-direction: column   ← wins

Same rule indices in the local prod build and on the deployed site.

The fix

Set the layout through Sidebar.Footer's Flex props. Apsara spreads ...props after its own direction, so the right utility classes are emitted and there's no cascade to lose — immune to bundling order:

<Sidebar.Footer className={styles.sidebarFooter} direction='row' align='center' justify='between'>

The four overridden declarations are dropped from the CSS module, which keeps only what Apsara doesn't set (gap, height, padding, border, background). .trigger { margin-left: auto } stays — it's what right-aligns the ? when there's no version switcher sibling.

Also: the mobile menu's static version label (rendered when a site has latest.label but no versions:) was a bare span reading as loose text under the full-width link rows. It now matches Sidebar.Item metrics. Scoped from the parent by element selector, so the desktop footer keeps its inline treatment and VersionSwitcher.tsx is untouched.

Testing

Verified against a production build, not dev:

Check Result
Footer, prod, 2 children Same row — identical centerY, version at left (12–29), ? at right (230–250)
Emitted classes direction-row / align-center / justify-between
CSS module survivors gap 4px, height 48px, padding 0 12px, border 0.5px — all intact
Mobile label vs real Sidebar.Item Identical min-height, height, width, padding, display, align-items, border-radius, color
Desktop label unaffected Still display: block, padding: 0

Lint (2 warnings) and typecheck (102 errors) both byte-identical to baseline — all pre-existing, none in the touched files.

Note

Every CSS-module-vs-Apsara-utility-class conflict in this repo is invisible in dev and only appears in prod. Preferring component props over CSS overrides avoids the class entirely.

Separately, build:examples:versioned is broken on main[MISSING_EXPORT] "images" is not exported by examples/versioned/versions/v1/dev/index.mdx:27. Unrelated and not fixed here, but that example can't be prod-tested until it is.

🤖 Generated with Claude Code

The default theme's sidebar footer sets its row layout in a CSS module,
but Apsara's `Sidebar.Footer` renders a `Flex` with `direction='column'`.
Both are single-class selectors with equal specificity, so the winner is
decided by stylesheet order.

Vite injects each CSS module as its own style tag in dev, where the
theme's module lands after Apsara's and wins. The production bundle
concatenates everything in chunk-graph order, which puts Apsara's flex
utilities after the theme module — so the tie flips and the footer
renders as a column. The version switcher and links menu ended up on
separate lines, only in built sites.

Set the layout through `Sidebar.Footer`'s Flex props instead. Apsara
spreads `...props` after its own `direction`, so the correct utility
classes are emitted and there is no cascade to lose. The overridden
declarations are dropped from the CSS module, leaving it the styling
Apsara does not set.

Also give the mobile menu's static version label the same metrics as a
sidebar item. With no `versions` configured, `VersionSwitcher` renders
`latest.label` as a bare span, which read as loose text beneath the
full-width link rows.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 31, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
chronicle Ready Ready Preview Aug 31, 2026 9:45am

@coderabbitai

coderabbitai Bot commented Aug 31, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 37 minutes.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 049a8fce-a819-4d0b-bc2c-589db731a975

📥 Commits

Reviewing files that changed from the base of the PR and between ba5161a and d9c494c.

📒 Files selected for processing (2)
  • packages/chronicle/src/themes/default/Layout.module.css
  • packages/chronicle/src/themes/default/Layout.tsx

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@rsbh
rsbh merged commit 885e450 into main Sep 1, 2026
9 checks passed
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.

2 participants