JoinMastodon Documentation

repository·main·Indexed 42 days ago

https://github.com/mastodon/joinmastodon

Documentation for joinmastodon.org, the informational landing portal for the Mastodon project. Built with Next.js, the site features internationalization via react-intl and Crowdin, real-time statistics fetching from the joinmastodon.org API, and a donation system integrated with Stripe.

Tokens
1.7K
Snippets
7
Records
11
Agent score
55%

What's inside JoinMastodon

  1. Optimize images for the site

    main
    When adding raster images, provide them at the maximum resolution they will be displayed at. If you do not require specific art direction, Next.js will automatically generate optimized mobile versions of the images.
  2. Deploy joinmastodon.org

    main

    The project must be hosted using a Node.js server (self-hosting) rather than a static HTML export. This requirement is necessary to support the following features:

    • Image Optimization: Automatic WebP conversion and compression.
    • Internationalized Routing: Localized versions of pages hosted at dedicated URLs for better SEO and crawling.
    • Redirects: Custom redirect logic configured in next.config.js.
  3. Manage translations with react-intl and Crowdin

    main

    Translations are managed via Crowdin and distributed using react-intl. The project follows a specific workflow for adding and syncing translations:

    1. Declare Messages: Use the <FormattedMessage> component in your source files to declare translatable strings.
    2. Extract Defaults: Run yarn extract to pull default messages into locales/en.json.
    3. Sync with Crowdin: Sync the locales/en.json file with the Crowdin project. New messages from the source will appear in Crowdin for translators, and new translations will be downloaded back into corresponding locale files (e.g., locales/es.json).
    4. Build: During the build process, each locale loads its messages via getStaticProps().
    yarn extract
  4. Install and run joinmastodon.org locally

    main

    To develop the site locally, ensure you have Node.js version 20 installed. This project uses yarn for dependency management. If yarn is not available, you can install it using corepack enable and corepack prepare yarn@1.

    Follow these steps to install dependencies and start the development server:

    yarn
    yarn run dev
  5. Server-side data fetching for DonatePage

    main

    The getServerSideProps function handles the initialization of the donation page by:

    1. Stripe Validation: Ensures process.env.STRIPE_PUBLIC_KEY is present.
    2. Seed Management: Checks for a seed cookie. If missing, it generates a random string (0-98) and sets it as an httpOnly cookie with a 15-minute expiry.
    3. API Request: Fetches active campaigns from the v1/donations/campaigns/active endpoint using fetchEndpoint. The request includes locale, platform (defaults to android), seed, source (defaults to menu), and a return_url.
    4. Environment Handling: If process.env.APP_ENV is not production, it adds environment=staging to the query parameters.
    5. Error Handling: If the API fetch fails, it returns notFound: true.

    Required Environment Variables:

    • STRIPE_PUBLIC_KEY: Required for the page to function.
    • APP_ENV: Used to determine if the request should target the staging environment.
    • NODE_ENV: Used to determine if the seed cookie should be secure.
  6. Use getStaticProps for static generation

    main

    The landing page uses getStaticProps to enable static site generation (SSG). It is exported using a wrapper function withDefaultStaticProps from the project's utilities.

    export const getStaticProps = withDefaultStaticProps()
  7. Fetch Mastodon statistics via API

    main

    The Metrics component in the About page retrieves real-time statistics by fetching data from the https://api.joinmastodon.org/statistics endpoint. The returned data is an array of objects representing different time periods. To calculate growth or changes, the component compares the second-to-last entry (days.data[days.data.length - 2]) as the currentDay against the first entry (days.data[0]) as the compareDay.

    // The underlying data fetch used by the Metrics component
    fetch("https://api.joinmastodon.org/statistics").then((res) => res.json())
  8. Implement a donation handler for the DonatePage

    main

    When building or extending a donation page using the DonatePage pattern, you can implement the OnDonateFn callback to redirect users to a checkout flow. The handler should construct a URL with the following parameters:

    • url: The base donation URL.
    • frequency: The donation frequency (e.g., one-time or recurring).
    • amount: The amount as a string, formatted with zero decimal places (e.g., amount.toFixed(0)).
    • currency: The selected currency.
    • theme: The current UI theme.

    Example implementation using next/navigation:

    const handleDonate: OnDonateFn = useCallback(
      async (amount, frequency, currency) => {
        const params = new URLSearchParams({
          url: donation_url,
          frequency,
          amount: amount.toFixed(0),
          currency,
          theme,
        })
        router.push(`/donate/checkout?${params.toString()}`)
      },
      [donation_url, router, theme]
    )
    const handleDonate: OnDonateFn = useCallback(
      async (amount, frequency, currency) => {
        const params = new URLSearchParams({
          url: donation_url,
          frequency,
          amount: amount.toFixed(0),
          currency,
          theme,
        })
        router.push(`/donate/checkout?${params.toString()}`)
      },
      [donation_url, router, theme]
    )
  9. Query parameters for the DonatePage

    main

    The DonatePage accepts several query parameters which are validated against a schema. These parameters allow for pre-configuring the donation widget:

    ParameterTypeDescription
    themethemeSchemaThe visual theme of the widget
    campaignstring (optional)Specific campaign identifier
    callbackstring (optional)Callback URL
    frequencyDONATION_FREQUENCIES (enum, optional)The donation frequency
    amountnumber (optional)An integer $\ge 100$ representing the amount
    currencyCURRENCIES (enum, optional)The selected currency

    Note: amount is coerced to an integer and must be positive and at least 100.

  10. Exported Home component

    main

    The Home component is the main landing page entrypoint for the application. It is a React component that renders the primary landing page layout, including the Hero section, Features, Why Mastodon, Testimonials, and Sponsors sections. It utilizes react-intl for internationalization and next/head for SEO metadata.

    export default Home
  11. Use mapBoardPositionToLabel for board member roles

    main

    When rendering the Board of Directors section, use the mapBoardPositionToLabel utility to transform raw position strings from the board data into human-readable labels for the UI.

    // Usage within the board mapping loop
    <span className="b2 block flex-grow !font-semibold text-gray-1">
      {mapBoardPositionToLabel(member.position)}
    </span>