LeetCode Stats Card

repository·main·Indexed 21 days ago

https://github.com/jacoblincool/leetcode-stats-card

A service for generating dynamically updated, customizable visual cards of LeetCode statistics for GitHub profiles and websites. It supports various themes, custom CSS, and extensions such as activity feeds, contest rating history, and heatmaps. The service can be used via a hosted endpoint or self-hosted using Docker and Cloudflare Workers.

Tokens
8.2K
Snippets
30
Records
36
Agent score
75%

What's inside leetcode-stats-card

  1. Use extended-card extensions

    main

    Extensions add specialized views to the card. Note: Currently, you can only use one extended-card extension at a time.

    Available extensions:

    • activity: Shows recent submissions.
    • contest: Shows contest rating history.
    • heatmap: Shows a heatmap of activity for the past 52 weeks.

    Pass the extension name via the ext parameter.

    # Activity extension
    ![](https://leetcard.jacoblin.cool/JacobLinCool?ext=activity)
    
    # Contest extension
    ![](https://leetcard.jacoblin.cool/JacobLinCool?ext=contest)
    
    # Heatmap extension
    ![](https://leetcard.jacoblin.cool/JacobLinCool?ext=heatmap)
  2. Display LeetCode stats on GitHub or websites

    main

    To show your LeetCode stats, use a Markdown image tag pointing to the LeetCode Stats Card endpoint. Replace JacobLinCool with your LeetCode username (case-insensitive).

    Standard Image:

    ![Leetcode Stats](httpshttps://leetcard.jacoblin.cool/JacobLinCool)

    Hyperlinked Image (links to your LeetCode profile):

    [![Leetcode Stats](https://leetcard.jacoblin.cool/JacobLinCool)](https://leetcode.com/JacobLinCool)
    ![Leetcode Stats](https://leetcard.jacoblin.cool/JacobLinCool)
  3. Self-host LeetCode Stats Card via Docker

    main

    You can self-host the service using the jacoblincool/leetcode-stats-card Docker image.

    To build the image manually, use the pnpm build:image script provided in the repository. An example docker-compose.yml is available in the repository root.

  4. Apply custom CSS via external stylesheets

    main

    You can inject custom CSS into the card by providing a comma-separated list of URLs to the sheets parameter. This is useful for advanced styling. You can host your CSS on services like GitHub Gist.

    ![](https://leetcard.jacoblin.cool/username?sheets=url1,url2)
    ![](https://leetcard.jacoblin.cool/jacoblincool?sheets=https://gist.githubusercontent.com/user/style.css)
  5. Extend the card generation process with Extensions

    main

    The Generator supports an extension system that allows you to modify the card's data or styles during the hydration phase. Extensions are passed as an array of initialization functions in the Config.extensions field.

    Each extension function is called with the following arguments:

    1. generator: The current Generator instance.
    2. data: The FetchedData retrieved from LeetCode.
    3. body: A record of UI element functions (e.g., Icon, Username).
    4. ext_styles: An array of strings that you can push to, which will be included in the final card's <style> block.

    Extensions can also return an object containing a name for logging purposes.

    // Example of a simple extension that adds custom CSS
    const myExtension = async (generator, data, body, ext_styles) => {
        ext_styles.push(".custom-class { color: blue; }");
        return { name: "my-extension" };
    };
    
    const config = {
        // ... other config
        extensions: [myExtension]
    };
  6. Extend the card using Extensions

    main

    You can customize the card's output by providing extensions. Extensions are initialized via ExtensionInit and executed as Extension functions.

    Extension Types

    1. ExtensionInit: A function that takes a Generator and returns a Promise<Extension> or an Extension directly. This is used to perform asynchronous setup before the extension runs.

    2. Extension: A function that receives the following arguments:

      • generator: The Generator instance.
      • data: The FetchedData object.
      • body: A record of functions (mapping to Item types) used to build the card's body.
      • styles: An array of existing CSS strings.

    An extension typically uses the body functions to inject custom HTML elements (represented as Item objects) into the card.

    type Extension = (
        generator: Generator,
        data: FetchedData,
        body: Record<string, (...args: unknown[]) => Item>,
        styles: string[],
    ) => Promise<void> | void;
    
    type ExtensionInit = (generator: Generator) => Promise<Extension> | Extension;
  7. How the Contest extension works

    main

    The ContestExtension is a feature of the LeetCode Stats Card that visualizes a user's contest rating history and current ranking.

    Key Features

    • Rating History Graph: Renders a polyline graph showing rating changes over time.
    • Current Stats: Displays current contest rating, highest rating achieved, and global ranking (e.g., 123 / 50000).
    • Badges: Automatically displays icons for specific LeetCode contest ranks like Guardian or Knight.
    • Dynamic Scaling: The extension automatically adjusts the card height (minimum 400px) and scales the graph based on the user's rating range and time span.

    Data Requirements

    This extension relies on the leetcode-query library to fetch userContestRanking and userContestRankingHistory. It only plots history for contests that the user has actually attended.

  8. Request the LeetCode Stats Card via Cloudflare Worker

    main

    The Cloudflare Worker implementation provides an endpoint to generate LeetCode stats cards as SVGs or HTML. You can request a card by providing a username as a path parameter or a query parameter.

    URL Patterns

    • By Username (Path): GET /<username>
    • By Username (Query): GET /?username=<username>
    • Demo Mode: If no username is provided, the worker returns a demo card.

    Query Parameters

    In addition to username, you can pass configuration options via query parameters to customize the card. One supported parameter is cache, which sets the cache-control max-age in seconds.

    https://your-worker-url.com/your_leetcode_username?cache=600
  9. Self-host using Docker Compose

    main

    You can run the LeetCode Stats Card worker using Docker Compose. The configuration defines a worker service that builds from the local directory and exposes port 8080. To persist the cache between restarts, a volume is mapped from the local ./.storage/cache directory to /worker/cache inside the container.

    version: "3.8"
    
    services:
        worker:
            build: .
            image: jacoblincool/leetcode-stats-card
            volumes:
                - ./.storage/cache:/worker/cache
            ports:
                - "8080:8080"
  10. Manage cache for the stats card

    main

    The cache duration is configurable via the cache parameter (in seconds).

    To manually clear the cache for a specific user/site, you can make a DELETE request to the endpoint: DELETE /:site/:username.

    Warning: Setting a very long cache time may result in GitHub caching the old card image instead of fetching the updated one.

  11. Configure themes for the LeetCode Stats Card

    main

    You can customize the appearance of the card using the theme and colors configuration keys.

    Using Built-in Themes

    You can specify a built-in theme by name using the theme key. You can also provide specific themes for light and dark modes using theme.light and theme.dark to support prefers-color-scheme media queries.

    Supported themes:

    • dark
    • forest
    • light
    • nord
    • unicorn
    • wtf
    • transparent
    • radical
    • chartreuse
    • catppuccinMocha

    Using Custom Colors

    To override themes with specific colors, provide an array of color strings via the colors key. The colors are mapped in the following order:

    1. colors[0] and colors[1]: Background colors (--bg-0, --bg-1)
    2. colors[2] and colors[3]: Text colors (--text-0, --text-1)
    3. colors[4] through colors[7]: Accent colors (--color-0 to --color-3)

    Custom colors have the highest precedence and will override theme settings.

    {
      "theme": "nord",
      "theme": {
        "light": "light",
        "dark": "dark"
      },
      "colors": ["#bg0", "#bg1", "#text0", "#text1", "#color0", "#color1", "#color2", "#color3"]
    }
  12. Configure fonts for the LeetCode Stats Card

    main

    You can customize the typography of your card using the font or fonts configuration keys. The system supports both built-in fonts and remote fonts fetched via the nano-font CDN.

    Built-in Fonts

    The following fonts are supported natively without requiring remote fetching:

    • baloo_2
    • milonga
    • patrick_hand
    • ruthie
    • source_code_pro

    Remote Fonts

    If a font name is provided that is not in the supported list, the generator attempts to fetch a JSON definition from https://cdn.jsdelivr.net/gh/JacobLinCool/nano-font@json/. The font name must match the filename pattern (spaces are replaced with underscores).

    Configuration Formats

    • Single Font: Use the font key with a string value.
    • Multiple Fonts: Use the fonts key with an array of strings. This allows for font fallbacks in the generated CSS.
    // Example: Single font configuration
    {
      "font": "baloo_2"
    }
    
    // Example: Multiple fonts for fallback
    {
      "fonts": ["Source Code Pro", "monospace"]
    }