Competitive Splatoon Platform
Go to file
Kalle f8319a2f96 Fix image form field rejecting uploads on browsers without canvas webp encoding
The SendouForm image field compresses the picked file client-side with
Compressor.js requesting "image/webp" output, which uses canvas.toBlob
under the hood. Per the HTML spec, browsers that can't encode the
requested type silently fall back to PNG instead of erroring (Safari /
all iOS browsers, Brave with fingerprint protection, older Android
WebViews). The resulting "data:image/png;base64," data URL rendered a
working preview but failed the zod schema's webp prefix check, showing
the user a bare "Invalid input" error with no way to upload.

Accept the png fallback in the schema and detect the actual format from
magic bytes on the server, storing the file with the matching extension
instead of always ".webp".
2026-06-10 21:45:42 +03:00
.claude New match page (#3032) 2026-05-04 18:15:10 +03:00
.github npm->pnpm (#2929) 2026-03-31 20:38:22 +03:00
.vscode Fix swiss pairing algorithm (#2446) 2025-07-10 20:17:58 +03:00
app Fix image form field rejecting uploads on browsers without canvas webp encoding 2026-06-10 21:45:42 +03:00
content/articles Stronghold Article "NA League 2026 Event 8 Regular Week 6" (#3121) 2026-05-31 18:32:27 +03:00
docs Convert edit teams form to SendouForm (#3138) 2026-06-04 20:38:24 +03:00
e2e Tabbed design for map pool on match profile 2026-06-04 21:07:02 +03:00
locales Placements suffix refactor, fix English shown when JP language selected 2026-06-06 11:55:23 +03:00
migrations 10 star weapon pool (#3108) 2026-06-01 18:20:47 +03:00
patches Silence react-router production server morgan log 2026-05-23 07:32:57 +03:00
public Update unranked icon to outlined version 2026-06-02 17:29:42 +03:00
scripts Migrate various tournament queries to Kysely (#3135) 2026-06-03 21:05:42 +03:00
types Add useEffect clean up to YouTube embed 2026-05-11 20:26:50 +03:00
.editorconfig Update editorconfig (#2285) 2025-05-18 12:12:53 +03:00
.env.example Add Sentry enabled FF 2026-05-16 07:25:00 +03:00
.env.test Bye bye .png 2026-03-29 16:48:47 +03:00
.gitattributes Add configs for better support of different development environments (#1092) 2022-11-05 22:45:00 +01:00
.gitignore npm->pnpm (#2929) 2026-03-31 20:38:22 +03:00
.nvmrc Update Node.js to 24 2026-04-01 18:08:46 +03:00
AGENTS.md Update AGENTS.md 2026-06-07 19:51:45 +03:00
biome.json Upgrade to React Router 7 (#2681) 2025-12-29 19:21:11 +02:00
CLAUDE.md Add AGENTS.md 2025-10-04 11:42:19 +03:00
CODE_OF_CONDUCT.md Better README & getting started (#2284) 2025-05-26 17:57:41 +03:00
compose.yaml Always pull latest skalop in the docker-compose file 2026-05-13 20:35:22 +03:00
CONTRIBUTING.md Better README & getting started (#2284) 2025-05-26 17:57:41 +03:00
db-test.sqlite3 10 star weapon pool (#3108) 2026-06-01 18:20:47 +03:00
desktop-bracket.png Update README screenshots 2026-04-19 14:38:58 +03:00
instrument.server.mjs Add Sentry 2026-05-09 15:41:20 +03:00
knip.ts Add Sentry 2026-05-09 15:41:20 +03:00
ley-driver.cjs Upgrade better-sqlite3 to v12 (#2685) 2025-12-30 21:18:49 +02:00
ley.config.cjs Upgrade better-sqlite3 to v12 (#2685) 2025-12-30 21:18:49 +02:00
LICENSE Update LICENSE 2024-09-15 08:51:07 +03:00
mobile-analyzer.png Update README screenshots 2026-04-19 14:38:58 +03:00
package.json build(deps): bump the minor-and-patch group across 1 directory with 15 updates (#3116) 2026-05-30 13:08:27 +03:00
playwright.config.ts Optimize E2E test run time (#2686) 2026-01-03 19:25:38 +02:00
pnpm-lock.yaml build(deps): bump the minor-and-patch group across 1 directory with 15 updates (#3116) 2026-05-30 13:08:27 +03:00
pnpm-workspace.yaml Silence react-router production server morgan log 2026-05-23 07:32:57 +03:00
react-router.config.ts Add Sentry 2026-05-09 15:41:20 +03:00
README.md Mention pnpm in README "Running locally" section 2026-04-26 07:19:48 +03:00
tsconfig.json Exclude scripts from main typecheck 2026-04-26 17:53:13 +03:00
vite.config.ts build(deps): bump the minor-and-patch group across 1 directory with 24 updates (#3095) 2026-05-23 18:15:15 +03:00
vitest.browser.config.ts Upgrade to Vite 8 (#2942) 2026-04-06 11:07:00 +03:00
vitest.unit.config.ts Add Sentry 2026-05-09 15:41:20 +03:00

sendou.ink - a Splatoon platform with competitive focus

What differentiates sendou.ink from some other gaming platforms (e.g. tournament hosting platforms) is its 100% focus on Splatoon. This allows for more custom tailored experience around the game and the community. The wide range of distinct features make it possible to create seamless integrations between them further enriching the user experience beyond what external integrations would allow.

Another key objective is to bridge the gap between casual and competitive players. For example, features like a gear build simulator can appeal not only to competitive players but also to those who simply want to enhance their gameplay without participating in tournaments. This allows sendou.ink to be useful for a wider audience but also provides a window to the competitive side of things for those that might be interested.

Screenshots
Selected features
  • Full tournament system
    • Automatic bracket progression
    • Single Elimination, Double Elimination, Round Robin, Swiss
    • Splatoon specific maplists (picked by the organizer or teams)
    • Counterpicking of different styles
    • Automatic seeding tool
    • Ranked tournaments allowing users to climb the leaderboard
    • View streams of tournament (both participants and the cast)
  • Seasonal ladder system
    • Join by yourself or with 1-3 of your mates, get a full group and challenge other teams
    • View streams of ongoing matches
    • Maplist generation based on given preferences
    • Private notes
  • Map planner that lets you draw on maps and insert weapons
  • Map list generation tool
  • Win badges from tournaments, management tools for TOs
  • Calendar to find out upcoming events to play in
  • Event result reporting
  • Plus Server for top players "looking for group purposes" voting and suggestion tools.
  • User pages
  • User search
  • "LFG", make a post to find people to play with
  • Scrim scheduler
  • Form teams (featuring uploading profile and banner pictures)
  • Object Damage Calculator (how much does each weapon deal vs. different objects)
  • Build Analyzer (exact stats of your builds)
  • Add and search for videos by weapon, stage, player and more
  • Auth via Discord
  • Light and dark mode
  • Localization

Running locally

Prerequisites

Optionally nvm can be convenient for managing multiple Node.js installs

Commands

First verify you have Node.js and git installed:

node --version
git --version
pnpm --version

You should see something like:

v22.13.0
git version 2.39.5 (Apple Git-154)
10.33.0

(if not then go back to "Prerequisites" and install what is missing)

Then there is a sequence of commands you need to run:

git clone https://github.com/sendou-ink/sendou.ink.git # Clones repository
cd sendou.ink # Change to the project's folder
pnpm install # Install dependencies
pnpm dev # Setup the development environment and run the project

You should then be able to access the application by visiting http://localhost:5173

Use the admin panel at http://localhost:5173/admin to log in (impersonate) as the admin user "Sendou" or as a regular user "N-ZAP" as well as re-seed the database if needed.

Docker

Optionally, if you want to develop image upload, real-time features or chat, you can use Docker to spin up the Skalop service and Minio for image hosting. You will need Docker up and running and then run the following command:

docker compose up -d

Minio admin UI to manage uploaded photos should be up and running at http://localhost:9001

Contributing

For developers reading the architecture.md file is highly recommended to get up to the speed with how the project folder structure works and getting familiar with its concepts.

Tech stack

  • Language: TypeScript
  • Frameworks: Node.js, React, Remix
  • UI Library: React Aria Components
  • Database: SQLite3 (via Kysely)
  • Styling: CSS Modules
  • Validation: Zod
  • Internationalization: i18next
  • Testing:
    • End-to-End (E2E): Playwright
    • Unit/Integration: Vitest