Skip to content

feat: add contributors page and improve navigation - #189

Open
imrja8 wants to merge 4 commits into
Dokploy:mainfrom
imrja8:fix/remove-redundant-careers-link
Open

imrja8 wants to merge 4 commits into
Dokploy:mainfrom
imrja8:fix/remove-redundant-careers-link

Conversation

@imrja8

@imrja8 imrja8 commented Sep 19, 2026

Copy link
Copy Markdown

Description

This PR adds a new /contributors page to highlight the open-source developers supporting Dokploy. By showcasing their names and contributions directly on the website, the goal is to show appreciation, encourage the community to come up with new solutions, and drive overall engagement. The PR also includes a few minor layout and navigation fixes.

Main Feature: The New Contributors Page

  • Built a new page to fetch and display all open-source contributors of the Dokploy repository in a responsive grid layout.
  • Strict Dynamic Pagination: Built an API route (/api/contributors) that parses GitHub's Link header to dynamically fetch every single contributor across unlimited pages (bypassing the standard 100-user API limit).
  • Accurate Commit Synchronization: A dual-fetch strategy uses /stats/contributors as a correction dictionary. This ensures the top users' commit counts match the GitHub Web UI by merging data from both endpoints.
  • Anonymous Summary Card: Groups "Anonymous" (unlinked) commits into a single summary card at the bottom of the grid (+X unlinked contributions). This prevents duplicate or broken user cards from filling up the UI.
  • API Safeguards & Fallbacks: Handles GitHub's 202 Accepted calculation status with a retry loop, and filters out non-human "bot" accounts. If the GitHub API fails or rate-limits, it falls back to a 1-hour stale memory cache.
  • Hydration & Crash Safe: Mobile and desktop layouts share exactly 40 skeletons on initial SSR load. Mobile devices use CSS (hidden md:flex) to instantly hide the bottom 20 items, resulting in zero React hydration mismatch errors. Added slicing checks to eliminate runtime crashes during HMR reloads.
  • Added avatars.githubusercontent.com to next.config.js to support remote avatars.

Minor Fixes & Navigation Cleanup:

  • Responsive Navbar Bugfix: Fixed a bug where the desktop navbar was breaking out of the canvas in shorter widths (768px-1279px), forcing the entire page to over-scroll horizontally.
  • Freed up Navbar Space: Removed the duplicate "Careers" link from the Desktop and Mobile navbars (Header.tsx) to make room for the new "Contributors" link. The "Jobs" link remains intact inside the "Resources" dropdown.
  • Unified Wording: Updated the "Careers" text to "Jobs" under the Company section in the footer (Footer.tsx), and updated the AI documentation file (llms.txt) to reference "Jobs" instead of "Careers".

Note for Reviewers (Architectural Judgements)

  • Why a Custom In-Memory Cache? : Instead of using standard Next.js fetch caching, the api/contributors route is set up to match the existing caching patterns used in github-stars and github-contributors. It uses a 1-hour in-memory cache, combined with a fallback helper that serves stale data and forces a cooldown if GitHub goes down.
  • Why a Dual-Fetch Strategy? : The paginated /contributors endpoint returns all 365+ users, but it inflates commit counts for top users. The /stats/contributors endpoint returns the accurate commit counts (matching the GitHub Web UI) but is capped at 100 users. Fetching both and merging them resolves the limitations of each endpoint.
  • Why CSS for Mobile Limits? : Instead of using Javascript (window.innerWidth) to limit the initial load to 20 on mobile (which causes hydration layout jumps), the server sends 40 items. The browser's native CSS engine hides the bottom 20 instantly on mobile before React even loads. This is a solid approach for jump-free responsive SSR design.
  • Why Client-Side Pagination? : Instead of hitting the server every time "Load More" is clicked, the server passes the full, cached array of contributors to the client component. Clicking "Load More" just reveals more of the array in the browser's memory, making the pagination instant and free of network requests.
  • Why shift the navbar collapse breakpoint to xl? : The desktop navbar requires approximately 1060px of horizontal space. Changing the collapse breakpoint to xl guarantees the desktop navbar only renders when there is at least 1216px of container width. This completely eliminates the horizontal over-scroll bug while safely displaying the hamburger menu on anything smaller.
  • Why swap the tablet buttons? : In the collapsed tablet view, the layout now relies entirely on the hamburger menu for links. Because the main buttons are already inside that menu, showing them again on the outside was redundant. The GitHub Stars widget was moved out by-side of the hamburger, as it is not inside the hamburger menu. Desktop and mobile views remain exactly as they were.

Checklist

  • The commit message follows the Conventional Commits specification
  • The documentation (llms.txt) is updated to reflect these changes
  • The website was run locally using pnpm run website:dev and changes were verified
  • Tested responsive layouts (Mobile, Tablet, Desktop)
  • Code is strictly typed, fully audited, and successfully passes biome check

Screenshots

1. The New Contributors Page:

Top of Page End of Page
Screenshot 2026-09-19 at 16 23 46 Screenshot 2026-09-19 at 16 24 23

2. Navbar Layout Fix (less screen width):

Before (Overflowing) After (Balanced)
Screenshot 2026-09-19 at 16 30 38 Screenshot 2026-09-19 at 16 30 13

@imrja8
imrja8 requested a review from Siumauricio as a code owner September 19, 2026 06:21
@imrja8

imrja8 commented Sep 19, 2026

Copy link
Copy Markdown
Author

@narcisonunez Can you please look into this.

@imrja8 imrja8 changed the title refactor(website): remove redundant careers link from navigation feat: add contributors page and improve navigation Sep 19, 2026
@imrja8

imrja8 commented Sep 19, 2026

Copy link
Copy Markdown
Author

@Siumauricio @narcisonunez

While doing some deep testing on the dual-fetch strategy, I discovered a rare but critical edge-case with how GitHub calculates rankings.

Because GitHub's exact stats API (/stats/contributors) strictly caps at 100 users, we use a second paginated API (/contributors) to fetch the remaining users. However, this second API often returns slightly inaccurate, inflated commit counts.

This creates a "Ranking Pollution" (Place Steal) bug: If a user is actually rank #105, but the second API wildly inflates their commits, they might suddenly look like rank #85. Because they aren't in the exact top 100 list, we can't correct their number. As a result, they steal a spot in the top 100 on our website, pushing a true top 100 contributor out and hiding them!

To prevent this, we have two options moving forward:

Option 1: Only show the Top 100 Users

We drop the pagination entirely and strictly use the accurate /stats/contributors API, stopping at 100 users.

  • Pros: 100% mathematically perfect commit counts. Matches exactly what GitHub's native UI does.
  • Cons: We don't list every single person.
  • Summary Card: The final card on the grid would say "+ X more unlisted users" to celebrate everyone outside the top 100.

Option 2: Show everyone, but accept slight inaccuracies

We drop the dual-fetch strategy and purely rely on the paginated /contributors API for everyone.

  • Pros: We get to show all 365+ users on the page.
  • Cons: Everyone's commit counts might be slightly inaccurate/inflated. However, because everyone is judged by the same flawed metric, the rankings remain fair and no one steals a spot.
  • Summary Card: The final card on the grid would say "+ X anonymous users".

Let me know which direction you'd prefer and I'll update the PR!

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