Skip to content

feat(home): editorial homepage, sticky top nav, and category drill-down#931

Open
jhislop-design wants to merge 1 commit into
mainfrom
jonny/distracted-hermann-e2cbe7
Open

feat(home): editorial homepage, sticky top nav, and category drill-down#931
jhislop-design wants to merge 1 commit into
mainfrom
jonny/distracted-hermann-e2cbe7

Conversation

@jhislop-design
Copy link
Copy Markdown

@jhislop-design jhislop-design commented May 19, 2026

Summary

Reframes the TanStack home and library-browse surfaces as an editorial review-site (Tom's Hardware / Top 10 Reviews) where every block is a teaser into a deeper page rather than one tall landing page. The contextual library left rail on docs pages is preserved.

What's new

Editorial homepage (/)

  • Featured Stack hero — TanStack Start branded card with the existing application-starter form embedded inline
  • Top Libraries leaderboard side rail (Query, Router, Table, Form)
  • Trust pillars (4 icon + label cards)
  • Trusted in production marquee (unchanged)
  • By the numbersHomeStatsSection deferred-loaded with editorial framing
  • Top picks by category — 4 cards, each a teaser into a category article
  • Latest writing — 4 most recent blog posts
  • Trusted partners — Gold / Silver / Bronze tiered with logo + tagline cards
  • Community pair — Discord + YouTube as compact 2-col CTAs

Sticky editorial top nav (sitewide)

  • Eyebrow strip + brand + 11 primary links + search + 2×3 social cluster (GitHub/Discord/YouTube/X/Bluesky/Instagram) + theme toggle
  • Pinned Gold Partners strip with logos + Sponsored tooltip on hover (`rel="sponsored"` for SEO honesty)
  • Sticky positioning publishes its rendered height into `--navbar-height` so the existing docs sidebar lines up underneath
  • Mobile drawer for the same nav at `< lg`

Category drill-down (`/stack/{state,ui,performance,tooling}`)

  • Buyer's-guide layout: breadcrumb → hero → Top Pick → quick-verdict table → ranked deep-dives → "How we think about it" criteria → related writing
  • Sticky right rail: in-guide TOC, "Compare across the stack" sibling links, back-to-libraries CTA

Pages that drop the left rail and use the editorial top nav

`/`, `/stack/$category`, `/libraries`, `/libraries/$framework`, `/partners`, `/blog`, `/showcase` (+ children), `/stats/npm`, `/merch`

Heads-up changes for maintainers

  • Railway promoted from bronze → gold partner tier. Please confirm — this affects the Gold strip and the home Partners section.
  • Removed several deferred home sections from the homepage render (`HomeSocialProofSection`, `HomeCommunitySection`, `HomeBytesSection`, standalone `HomeApplicationStarter`). Components themselves are untouched — only the homepage layout no longer mounts them. Easy to add back wherever.
  • Dev-only: `src/utils/documents.server.ts` gains a `DATABASE_URL`-missing fallback so docs pages render in dev without a local Postgres. Prod path is unchanged.

Test plan

  • `pnpm format` — only touched files in this PR
  • `pnpm test` (tsc + lint) — 0 errors
  • `pnpm test:smoke` — 10/10 (home, blog, ethos, query/router/table docs, OG images)
  • `pnpm build` — clean
  • Manual: `/`, `/stack/state`, `/stack/ui`, `/stack/performance`, `/stack/tooling`, `/libraries`, `/partners`, `/blog`, `/showcase`, `/stats`, `/merch`, `/router/latest` all render correctly at `1440x900`. Sticky nav stays pinned. Active state (cyan pill) tracks current page.

Open questions for @tannerlinsley

  1. Railway → gold: ship it, or keep at bronze and pin via a separate "Featured partner" mechanism?
  2. The 4 removed deferred home sections — keep them off home, or want them somewhere on the editorial home (and where)?
  3. Comfortable having the editorial top nav globally, or scope it back to just the homepage + `/stack/*`?

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added stack buyer's guide with comprehensive category articles for state management, UI frameworks, performance tools, and tooling solutions
    • Redesigned homepage with editorial layout featuring library leaderboards, featured content, partner tiers, and community calls-to-action
    • Introduced editorial top navigation with primary navigation links, search functionality, social links, and theme toggle
    • Enhanced document fetching with fallback caching support
    • Updated Railway partner status to gold tier

Review Change Stack

Reframes the home and library-browse surfaces as an editorial review
site (Tom's Hardware / Top 10 Reviews vibe) where every block is a
teaser into a deeper page rather than a single tall landing.

New surfaces
- src/components/home/HomeEditorial.tsx: featured Start hero with
  embedded application starter, top-libraries leaderboard side rail,
  trust pillars, Trusted-By marquee, live OSS Stats deferred section,
  four "Top picks by category" cards, latest writing, tiered partners
  (Gold/Silver/Bronze), Discord + YouTube community pair.
- src/components/editorial/EditorialTopNav.tsx: sticky global top nav
  (eyebrow strip + brand + 11-item primary nav + search + compact 2x3
  social cluster + theme + mobile drawer) and a pinned Gold Partners
  strip with "Sponsored" hover tooltips.
- src/components/stack/* + src/routes/stack.\$category.tsx: four
  buyer's-guide-style category articles
  (/stack/{state,ui,performance,tooling}) with hero, Top Pick, quick
  verdict table, ranked list, criteria block, related writing and a
  sticky right-rail TOC + cross-category compare.

Global shell
- src/routes/__root.tsx: render EditorialTopNav on every page; non-
  editorial pages still wrap children with <Navbar hideHeader> so the
  contextual library left rail is preserved on docs pages.
- src/components/Navbar.tsx: add hideHeader prop. When true the global
  Navbar skips its own fixed top header and lets EditorialTopNav own
  --navbar-height (published by EditorialTopNav via ResizeObserver).

Page opt-ins
- /, /stack/\$category, /libraries, /libraries/\$framework, /partners,
  /blog, /showcase + children, /stats/npm, /merch all set
  staticData.showNavbar: false to drop the library left rail and use
  the editorial top-nav-only layout.

Data and dev DX
- src/utils/partners.tsx: promote Railway from bronze -> gold.
- src/utils/documents.server.ts: when DATABASE_URL is unset (dev
  without Postgres), fall back from getCachedGitHubTextFile to the
  in-memory fetchCached path so library docs pages render locally
  without a DB.

Notes for reviewers
- Removed deferred home sections (HomeSocialProofSection,
  HomeCommunitySection, HomeBytesSection, standalone
  HomeApplicationStarter usage) are kept as components -- only their
  homepage render is gone.
- routeTree.gen.ts is regenerated by the build; included for
  completeness.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 19, 2026

📝 Walkthrough

Walkthrough

This PR introduces an editorial layout system with a new top navigation component, replaces the home page with an editorial design, adds buyer's guide pages for stack categories, and applies the editorial pattern across multiple routes by suppressing the left sidebar navigation where appropriate.

Changes

Editorial Navigation and Stack Categories

Layer / File(s) Summary
Navbar hideHeader prop
src/components/Navbar.tsx
Navbar accepts an optional hideHeader prop that skips CSS variable measurement and conditionally hides the fixed navbar element while adjusting content padding.
Category types and metadata
src/components/stack/stack-categories.ts
Defines CategorySlug and GroupId types, bidirectional slug/group mappings, and per-category metadata including names, intros, criteria, and accent gradients for state, ui, performance, and tooling categories.
EditorialTopNav component
src/components/editorial/EditorialTopNav.tsx
Sticky header with category-based primary navigation, search button, social links, theme toggle, mobile drawer, and a gold-tier partners strip featuring active sponsors with hover tooltips.
CategoryArticle buyer's guide page
src/components/stack/CategoryArticle.tsx
Two-column page layout rendering editors' pick hero, quick verdict list, ranked libraries, criteria grid, related posts, and a sticky right rail with table of contents and category links.
Stack category routing
src/routes/stack.$category.tsx, src/routeTree.gen.ts
File route at /stack/$category with slug validation, metadata loader, SEO head, and component rendering. Generated route tree integrates the new route into all type mappings.
HomeEditorial page component
src/components/home/HomeEditorial.tsx
Editorial homepage replacing the prior Index route, featuring starter card, leaderboards, trust pillars, marquee, lazy-loaded stats, category leaderboards, blog cards, partner tiers, and community CTAs.
Root layout with EditorialTopNav integration
src/routes/__root.tsx
Root shell now imports and renders EditorialTopNav before main content. Navbar usage updated to conditionally pass hideHeader when left sidebar is hidden.
Editorial routes suppress left sidebar
src/routes/index.tsx, src/routes/blog.tsx, src/routes/libraries.tsx, src/routes/libraries_.$framework.tsx, src/routes/merch.tsx, src/routes/partners.tsx, src/routes/showcase/*.tsx, src/routes/stats/npm/index.tsx
Routes set staticData.showNavbar: false to disable the global left-rail navigation, enabling the editorial top nav pattern across home, content, and showcase surfaces.
Supporting changes
src/utils/partners.tsx, src/utils/documents.server.ts
Railway partner tier updated from bronze to gold. Server-side fetchRepoFile adds DATABASE_URL fallback to use in-memory cache with direct fetch when database is unavailable.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Poem

A new top nav sails across the page,
Editorial grace on a modern stage.
Categories shine with their buyer's guide,
Partners gleam in a gold-trimmed stride.
The rabbit hops through layered UI,
Where sidebars rest and headers fly! 🐰✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 29.73% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title clearly and concisely describes the main changes: adding an editorial homepage, implementing a sticky top navigation, and creating category drill-down pages.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jonny/distracted-hermann-e2cbe7

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


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 and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/editorial/EditorialTopNav.tsx`:
- Around line 124-131: The Search button in EditorialTopNav is rendered as an
active control but lacks any click handler; either wire it to the search action
(e.g., call the existing openSearch / onOpenSearch / toggleSearchModal prop or
dispatch a search-open action from EditorialTopNav) or mark it non-interactive
by adding the disabled attribute and adjusting aria-disabled/title to reflect
unavailability (or hide it). Locate the button element in EditorialTopNav (the
one with aria-label="Search (⌘K)" and <Search /> icon) and either attach the
proper onClick handler that opens the search UI or change its attributes/classes
to disabled/hidden and update accessible labels accordingly.

In `@src/components/stack/CategoryArticle.tsx`:
- Line 129: The section element in CategoryArticle.tsx uses id={library.id} in
two places, causing duplicate IDs; update both occurrences to produce unique IDs
(for example append a stable suffix such as the library index, type, or role) so
each section id is distinct — e.g. replace id={library.id} with something like
id={`${library.id}-${index}`} or id={`${library.id}-editors`} in the
editor's-pick render path and any other place that reused library.id, and ensure
any internal anchor links/refs that relied on library.id are updated to match
the new unique id format.
- Around line 32-34: relatedPosts can contain the same post multiple times (from
different libraries) causing duplicate entries and key collisions with
post.slug; dedupe the array returned from libraries.flatMap by post identifier
(e.g., post.id or post.slug) before calling slice(0, 4) so you only pick unique
posts, then render those; also update the list key usage (where post.slug is
used) to a truly unique key if you intentionally render duplicates (e.g.,
`${post.slug}-${lib.id}`) or just use post.id after deduping to avoid
collisions.

In `@src/routes/__root.tsx`:
- Line 235: The Navbar is always rendered with hideHeader enabled which hides
the header/menu trigger; change the prop so it reflects the hideNavbar flag
instead of always being true — replace the current JSX that renders <Navbar
hideHeader>{children}</Navbar> with <Navbar
hideHeader={hideNavbar}>{children}</Navbar> (or simply
<Navbar>{children}</Navbar> if you want the header shown when hideNavbar is
false) so the Navbar header/menu trigger remains available when appropriate;
update the expression around hideNavbar/children accordingly.

In `@src/utils/documents.server.ts`:
- Around line 412-421: The dev-only in-memory fallback is being triggered
whenever DATABASE_URL is unset, bypassing the InvalidCacheKeyError guard; change
the condition so the fallback runs only in development (e.g.,
process.env.NODE_ENV === 'development') and/or a dedicated dev flag, and keep
the InvalidCacheKeyError guard in place: update the block that calls
fetchCached({ key, ttl, fn: () => fetchRepoFileFromOrigin(repoPair, ref,
filepath) }) to run only when in dev, and ensure any InvalidCacheKeyError thrown
during cache/key validation (the existing InvalidCacheKeyError path) still
bubbles or is handled before falling back to fetchRepoFileFromOrigin.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ccb3d127-13be-4ac8-bc61-86347e5eb31a

📥 Commits

Reviewing files that changed from the base of the PR and between 231bc91 and dbe2ca7.

📒 Files selected for processing (21)
  • src/components/Navbar.tsx
  • src/components/editorial/EditorialTopNav.tsx
  • src/components/home/HomeEditorial.tsx
  • src/components/stack/CategoryArticle.tsx
  • src/components/stack/stack-categories.ts
  • src/routeTree.gen.ts
  • src/routes/__root.tsx
  • src/routes/blog.tsx
  • src/routes/index.tsx
  • src/routes/libraries.tsx
  • src/routes/libraries_.$framework.tsx
  • src/routes/merch.tsx
  • src/routes/partners.tsx
  • src/routes/showcase/$id.tsx
  • src/routes/showcase/edit.$id.tsx
  • src/routes/showcase/index.tsx
  • src/routes/showcase/submit.tsx
  • src/routes/stack.$category.tsx
  • src/routes/stats/npm/index.tsx
  • src/utils/documents.server.ts
  • src/utils/partners.tsx

Comment on lines +124 to +131
<button
type="button"
aria-label="Search (⌘K)"
title="Search · ⌘K"
className="hidden h-9 w-9 items-center justify-center rounded-md text-zinc-600 hover:bg-zinc-100 hover:text-zinc-900 sm:flex dark:text-zinc-400 dark:hover:bg-zinc-800 dark:hover:text-white"
>
<Search size={16} />
</button>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Make the search control functional or explicitly disabled.

Line 124 renders an active button with a search affordance/title, but it has no click behavior. This creates a broken primary-nav action for users.

Suggested direction
-          <button
+          <button
             type="button"
             aria-label="Search (⌘K)"
             title="Search · ⌘K"
+            onClick={openSearch} // wire existing command palette/search entry point
             className="hidden h-9 w-9 items-center justify-center rounded-md text-zinc-600 hover:bg-zinc-100 hover:text-zinc-900 sm:flex dark:text-zinc-400 dark:hover:bg-zinc-800 dark:hover:text-white"
           >
             <Search size={16} />
           </button>

If search is not ready yet, render it disabled/hidden instead of interactive.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/editorial/EditorialTopNav.tsx` around lines 124 - 131, The
Search button in EditorialTopNav is rendered as an active control but lacks any
click handler; either wire it to the search action (e.g., call the existing
openSearch / onOpenSearch / toggleSearchModal prop or dispatch a search-open
action from EditorialTopNav) or mark it non-interactive by adding the disabled
attribute and adjusting aria-disabled/title to reflect unavailability (or hide
it). Locate the button element in EditorialTopNav (the one with
aria-label="Search (⌘K)" and <Search /> icon) and either attach the proper
onClick handler that opens the search UI or change its attributes/classes to
disabled/hidden and update accessible labels accordingly.

Comment on lines +32 to +34
const relatedPosts = libraries
.flatMap((lib) => getPostsForLibrary(lib.id).map((p) => ({ post: p, lib })))
.slice(0, 4)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

De-duplicate related posts before slicing/rendering.

Lines 32-34 can include the same blog post multiple times (across multiple libraries), and Line 419 then reuses post.slug keys, which can collide.

Minimal fix
-  const relatedPosts = libraries
-    .flatMap((lib) => getPostsForLibrary(lib.id).map((p) => ({ post: p, lib })))
-    .slice(0, 4)
+  const relatedPosts = Array.from(
+    new Map(
+      libraries
+        .flatMap((lib) =>
+          getPostsForLibrary(lib.id).map((p) => ({ post: p, lib })),
+        )
+        .map((item) => [item.post.slug, item] as const),
+    ).values(),
+  ).slice(0, 4)

Also applies to: 417-419

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/stack/CategoryArticle.tsx` around lines 32 - 34, relatedPosts
can contain the same post multiple times (from different libraries) causing
duplicate entries and key collisions with post.slug; dedupe the array returned
from libraries.flatMap by post identifier (e.g., post.id or post.slug) before
calling slice(0, 4) so you only pick unique posts, then render those; also
update the list key usage (where post.slug is used) to a truly unique key if you
intentionally render duplicates (e.g., `${post.slug}-${lib.id}`) or just use
post.id after deduping to avoid collisions.

accent: { from: string; to: string }
}) {
return (
<section id={library.id} className="scroll-mt-6">
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Avoid duplicate element IDs for the editor’s pick library.

Line 129 and Line 297 can produce the same id, which makes in-page anchors ambiguous and violates unique-id constraints.

Minimal fix
-    <section id={library.id} className="scroll-mt-6">
+    <section id={`top-pick-${library.id}`} className="scroll-mt-6">

Also applies to: 297-297

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/stack/CategoryArticle.tsx` at line 129, The section element in
CategoryArticle.tsx uses id={library.id} in two places, causing duplicate IDs;
update both occurrences to produce unique IDs (for example append a stable
suffix such as the library index, type, or role) so each section id is distinct
— e.g. replace id={library.id} with something like id={`${library.id}-${index}`}
or id={`${library.id}-editors`} in the editor's-pick render path and any other
place that reused library.id, and ensure any internal anchor links/refs that
relied on library.id are updated to match the new unique id format.

Comment thread src/routes/__root.tsx
<PageViewTracker />
{hideNavbar ? children : <Navbar>{children}</Navbar>}
<EditorialTopNav />
{hideNavbar ? children : <Navbar hideHeader>{children}</Navbar>}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

hideHeader is always enabled here, which can leave left-rail navigation inaccessible.

On Line 235, hideHeader is passed as a boolean shorthand, so it is always true whenever Navbar renders. That removes the Navbar header/menu trigger, but the sidebar still depends on that trigger on non-inline layouts.

Suggested fix
-            {hideNavbar ? children : <Navbar hideHeader>{children}</Navbar>}
+            {hideNavbar ? children : <Navbar hideHeader={hideNavbar}>{children}</Navbar>}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/routes/__root.tsx` at line 235, The Navbar is always rendered with
hideHeader enabled which hides the header/menu trigger; change the prop so it
reflects the hideNavbar flag instead of always being true — replace the current
JSX that renders <Navbar hideHeader>{children}</Navbar> with <Navbar
hideHeader={hideNavbar}>{children}</Navbar> (or simply
<Navbar>{children}</Navbar> if you want the header shown when hideNavbar is
false) so the Navbar header/menu trigger remains available when appropriate;
update the expression around hideNavbar/children accordingly.

Comment on lines +412 to +421
// Dev fallback: when there is no DATABASE_URL configured, the DB-backed
// GitHub cache cannot run. Use an in-memory cache and a direct raw fetch
// so docs pages still work without a local Postgres.
if (!process.env.DATABASE_URL) {
return fetchCached({
key,
ttl: 60_000,
fn: () => fetchRepoFileFromOrigin(repoPair, ref, filepath),
})
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Dev fallback is currently active in all environments and skips invalid-path protection.

Line 415 enables this path whenever DATABASE_URL is missing, not just in development, and it bypasses the InvalidCacheKeyError guard path. That can mask prod misconfig and allow malformed paths to hit origin fetches.

Suggested patch
-  if (!process.env.DATABASE_URL) {
+  if (process.env.NODE_ENV === 'development' && !process.env.DATABASE_URL) {
+    if (!isValidFilepath(filepath)) {
+      return null
+    }
     return fetchCached({
       key,
       ttl: 60_000,
       fn: () => fetchRepoFileFromOrigin(repoPair, ref, filepath),
     })
   }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/utils/documents.server.ts` around lines 412 - 421, The dev-only in-memory
fallback is being triggered whenever DATABASE_URL is unset, bypassing the
InvalidCacheKeyError guard; change the condition so the fallback runs only in
development (e.g., process.env.NODE_ENV === 'development') and/or a dedicated
dev flag, and keep the InvalidCacheKeyError guard in place: update the block
that calls fetchCached({ key, ttl, fn: () => fetchRepoFileFromOrigin(repoPair,
ref, filepath) }) to run only when in dev, and ensure any InvalidCacheKeyError
thrown during cache/key validation (the existing InvalidCacheKeyError path)
still bubbles or is handled before falling back to fetchRepoFileFromOrigin.

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.

1 participant