LogoRead Frog

Code Contribution

Let's build a better language learning product together

Getting Started

Step 1: Fork the repository and clone it to your local machine

# Clone the repository from your fork
git clone https://github.com/xxxxx/read-frog.git

# Enter the project directory
cd read-frog

Step 2: Set up and initialize local database

You can set up any Postgres database of your choice locally. It is recommended to use Supabase local development. Skip step 2.1 if using non-Supabase deployments.

Step 2.1: Supabase local deployment

To set up the database required by the project, go to the Supabase local development set up guide to create a local Supabase instance for local development. After the step, a new folder supabase will be created under the project root. Never commit this folder as it is only for local development.

After initialization, run the following command to check local instance running status:

supabase status

You'll see output like the following:

         API URL: http://xxxxxxx
     GraphQL URL: http://xxxxxxx
  S3 Storage URL: http://xxxxxxx
          DB URL: postgresql://xxxxxxx
      Studio URL: http://xxxxxxx
    Inbucket URL: http://xxxxxxx
      JWT secret: xxxxxxx
        anon key: xxxxxxx
service_role key: xxxxxxx
   S3 Access Key: xxxxxxx
   S3 Secret Key: xxxxxxx
       S3 Region: xxxxxxx

Note down the value of DB URL for use in future steps.

Step 2.2: Initialize local database schema

Create a file .env under <project_root>/packages/db/. In that file, define a variable DATABASE_URL and fill in the full database connection URL. If using Supabase from step 2.1, fill in DB URL obtained in that step.

Example <project_root>/packages/db/.env:

DATABASE_URL=postgresql://postgres:postgres@127.0.0.1:54322/postgres
NODE_ENV=development

Or you can copy the example file:

# On Unix/Linux/macOS:
cp packages/db/.env.example packages/db/.env

# On Windows (Command Prompt):
copy packages\db\.env.example packages\db\.env

# On Windows (PowerShell):
Copy-Item packages/db/.env.example packages/db/.env

Then, run the following command to initialize database schemas:

pnpm db:migrate

Step 3: Set up environment

Create a file .env.local under <project_root>/apps/website/. In that file, define values for all the environment variables declared in <project_root>/apps/website/env.ts. In particular:

  • BETTER_AUTH_SECRET: Setting any value is fine. It is being used as seed for encryption.
  • BETTER_AUTH_URL: Same as website URL.
  • GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET: Google SSO keys. Set with random values if no need to log in locally. Otherwise, apply one on Google.
  • DATABASE_URL: Complete URL to connect to the Postgres database. If using Supabase from step 2.1, fill in DB URL obtained in that step.
  • PUBLIC_REPO_GITHUB_TOKEN: For displaying Github starred count. (Optional)

Example <project_root>/apps/website/.env.local:

BETTER_AUTH_SECRET=<SOME_BETTER_AUTH_SECRET>
BETTER_AUTH_URL=http://localhost:8888

GOOGLE_CLIENT_ID=<SOME_GOOGLE_CLIENT_ID>
GOOGLE_CLIENT_SECRET=<SOME_GOOGLE_CLIENT_SECRET>

DATABASE_URL=postgresql://postgres:postgres@127.0.0.1:54322/postgres

# Optional โ€“ only needed if you want the deal with rate limit of Github API
PUBLIC_REPO_GITHUB_TOKEN=<SOME_PUBLIC_REPO_GITHUB_TOKEN>

Or you can copy the example file:

# On Unix/Linux/macOS:
cp apps/website/.env.example apps/website/.env.local

# On Windows (Command Prompt):
copy apps\website\.env.example apps\website\.env.local

# On Windows (PowerShell):
Copy-Item apps/website/.env.example apps/website/.env.local

Step 4: Start dev server

Run the following command to start local development server:

pnpm dev

After startup, access the main website at: http://localhost:8888/.

Development Tips

Using npx with pnpm Node.js Management

We're using pnpm's built-in Node.js version management (introduced in pnpm 10.14). You may encounter EBADDEVENGINES errors when running npx commands. There are two solutions:

Solution 1: Use pnpm dlx or pnpx instead of npx

# Instead of npx
npx some-package@latest

# Use pnpm dlx
pnpm dlx some-package@latest

# Or use pnpx (alias for pnpm dlx)
pnpx some-package@latest

Solution 2: Align Node.js version with pnpm

When it's not convenient to replace npx (e.g., for user-scoped MCP installations in Claude Code), align your Node.js version:

# Install and use the required Node.js version globally
pnpm env use --global 22.18.0

Open the extension in the specific browser

You can modify the web-ext.config.ts file in the apps/extension directory to explicitly specify the browser path.

// apps/extension/web-ext.config.ts
import { defineWebExtConfig } from 'wxt';

export default defineWebExtConfig({
  binaries: {
      chrome: "path/to/your/chrome.exe",
      firefox: "path/to/your/firefox.exe",
      edge: "path/to/your/edge.exe"
    }
});

pnpm dev can't load the extension automatically

If you use Chrome version 137 or higher, you need to download Chrome for Testing for development. See details.

Persistent Chrome Profile

By default, web-ext creates a new profile every time you run the dev script.

Only Chromium browsers support persistent profiles with --user-data-dir flag:

export default defineWebExtConfig({
  chromiumArgs: ['--user-data-dir=./.wxt/chrome-data'],
});

Benefits: Your profile persists between dev sessions, so you can:

  • Install devtools extensions
  • Remember logins
  • Keep browser settings

๐Ÿ’ก TIP: Use any directory for --user-data-dir. Current config creates a profile per project.

Breakpoint Debugging Issues

โš ๏ธ If you encounter issues with breakpoint debugging, it might be due to Chrome DevTools ignore list settings. Content scripts injected by extensions may be automatically ignored, causing breakpoints to fail.

Solution:

  1. Open DevTools on any webpage
  2. Click the settings icon (โš™๏ธ) in the top right corner
  3. Select "Ignore list" from the left navigation
  4. Ensure the "Content scripts injected by extensions" option is unchecked

Chrome Ignore List

Submitting Code

Create a new branch

# For new features
git checkout -b feat/the-feature

# For bug fixes
git checkout -b fix/the-bug

# For docs modify
git checkout -b docs/the-docs

Merge Branch

If the remote main branch gets updated and creates conflicts in our PR, you can resolve it by merging the remote branch in advance .

# Switch to the main branch
git checkout main

# Pull the latest code from upstream
git pull upstream main

# Switch back to your local branch
git checkout docs/xxxx

# Merge the main branch into your local branch
git rebase main

# Push the code again if there are conflicts after rebase
git push --force-with-lease origin docs/xxxx

# If there are no conflicts, push the code again
git push origin docs/xxxx

Fatal in syncing the upstream repository

If you encounter this error while syncing the upstream repository

fatal: 'upstream' does not appear to be a git repository
fatal: Could not read from remote repository.

Please try to manually add an upstream repository

git remote add upstream https://github.com/mengxi-ream/read-frog

Generating Pull Request

Before generating a Pull Request, you need to add a changeset

# Add Changeset
pnpm changeset

# Choose Packages
# Which packages would you like to include?...
[] @read-frog/website
[] @read-frog/extension

# Select a appropriate bump type for above packages
# Which packages should have a major bump? (major)
( ) all packages
  ( ) @read-frog/website@0.1.0
  ( ) @read-frog/extension@0.1.0
# Which packages should have a minor bump? (minor)
( ) all packages
  ( ) @read-frog/website@0.1.0
  ( ) @read-frog/extension@0.1.0
# The following packages will be patch bumped (patch)
( ) all packages
  ( ) @read-frog/website@0.1.0
  ( ) @read-frog/extension@0.1.0

# Commit Summary
Summary >> ....

pnpm changeset will generate [uniqId].md in the .changeset file, and the description of this changeset can be adjusted again after the generation is completed.

Then create a Pull Request and wait for it to be merged.

Commit Convention

We use the Conventional Commits specification for writing commit messages.

Set environment variables

To automatically load environment variables while developing the extension, such as API keys for the development environment, you can create a .env.local file in the apps/extension directory.

# apps/extension/.env.local
WXT_OPENAI_API_KEY=xxx
WXT_DEEPSEEK_API_KEY=xxx

Skip Google API Tests in China

If you are a contributor from mainland China, when you need to push code, use the following command:

# MAC
SKIP_FREE_API=true git push

# WINDOWS
$env:SKIP_FREE_API='true'
git push

Why is this necessary? Because code tests are performed during the push process, but Google's free API is inaccessible in mainland China. This would cause the tests to fail and the push to be rejected. By setting the SKIP_FREE_API environment variable, we skip the Google tests.

What kind of PRs will be reviewed and merged?

Getting Started with Contributions

If this is one of your first PRs, and you are serious about contributing, it generally won't be rejected due to quality issues. Maintainers will help you identify problems and adapt to our development process and code style. However, we strongly recommend following these guidelines:

  1. Start with small issues, such as "Good First Issue" in the repository. Small, simple PRs provide a smooth learning process.
  2. Ensure your PR passes all GitHub Actions and local tests.

Why isn't my PR getting reviewed by maintainers?

  1. You contributed an overly complex PR before familiarizing yourself with the codebase, resulting in too many required changes.
  2. Your code contains many basic errors, making maintainers question your seriousness:
    • Unused code snippets that weren't removed
    • Excessive repetitive code
    • Variable and function names are too arbitrary
    • We encourage AI-assisted development, but you didn't carefully review the AI-generated code, leading to low-quality, unmaintainable, or over-engineered code
  3. Maintainers provided modification suggestions multiple times, but you either didn't follow them or your changes didn't address the root issues.