AniSauce
Overview
AniSauce is a Next.js 16 web application that helps users “find the sauce” for anime screenshots. It accepts still frames via drag-and-drop, clipboard paste, direct URL entry, or manual file selection, queries the trace.moe reverse-image search API, enriches matches with AniList metadata, and renders an immersive preview card that highlights the probable title, episode, timestamp, synopsis, and similarity score. The app is optimized for quick, keyboard-friendly searches, includes dark/light theming, and persists the most recent result in sessionStorage so the /preview route can be refreshed independently from the landing page.
Core Features
- Multi-input search surface -
SearchFormaccepts pasted URLs, typed text, andctrl/cmd + vclipboard data whileuseSauceSearchalso listens for global paste events and drag-and-drop (handleDragEnter/Leave/Over/Drop) to route either an image file or a URL into the same search pipeline. - Status-driven UX -
SearchStatusdisplays contextual, optimistic updates such as “Contacting trace.moe…” and error guidance supplied by the hook, keeping the user informed through every asynchronous phase. - Trace.moe + AniList enrichment -
searchTraceMatchhits trace.moe (with optional API key headers) andbuildResultFromMatchmerges its response with the AniList GraphQL API so the preview card can show cover art, banners, synopsis, score, and outbound links. - Result hand-off to
/preview-saveResultwrites the resolvedSearchResultintosessionStorage. The/previewpage loads it (loadResult) on mount, renders either an auto-playing clip or the fallback still frame, and exposes quick navigation (new search,view on anilist). - Media-friendly preview -
buildVideoUrlensures trace.moe-provided MP4s load with a large size parameter, whileformatTimestampconverts second offsets intomm:ssfor the “Sauce” line. - Theme system -
ThemeProvider+ThemeTogglesynchronize the chosen theme tolocalStorage, update thedata-themeattribute, and ensure a flicker-free initial render via an inline<Script>inapp/layout.tsx. CSS custom properties inapp/globals.cssdrive both palettes.
Architecture at a Glance
| Layer | Responsibility | Key Files |
|---|---|---|
| App shell | Root layout, fonts, Font Awesome, theme bootstrapping | app/layout.tsx, app/globals.css |
| Search feature module | UI components, hook orchestration, service layer, utilities | app/features/search/** |
| Theme feature module | Context provider and toggle control | app/features/theme/** |
| Shared library utilities | API clients, storage, media helpers, formatting | app/lib/*.ts, app/types.ts |
| Routes | app/page.tsx mounts SauceSearchScreen; app/preview/page.tsx renders stored results | app/page.tsx, app/preview/page.tsx |
The primary data flow is:
- User provides an image (file, drop, paste, or URL) through
SauceSearchScreen. useSauceSearchnormalizes the payload and callssearchTraceMatch.- On success,
buildResultFromMatchenriches the match with AniList data and writes it viasaveResult. - The user is redirected to
/preview, which reads the cached result and displays the media card with optional streaming clip.
External Services & Data Handling
- trace.moe REST API - Queried through an Axios instance (
traceInstance) defined inapp/lib/api.ts. An optional API key can be provided viaNEXT_PUBLIC_API_KEY,NEXT_PUBLIC_TRACE_KEY, orAPI_KEY, added to thex-trace-keyheader automatically. - AniList GraphQL API - Queried via
aniListInstanceusing the bundledANI_LIST_QUERY. Failures are caught and logged, falling back to trace.moe metadata when AniList is unavailable. - Browser storage -
sessionStorageretains the last successful search result;localStoragestores the user’s theme preference.
Tech Stack
- Framework - Next.js 16 (App Router) with React 19 and TypeScript 5.
- Styling - Global CSS variables plus CSS Modules (
app/page.module.css) for scoped layouts; Google Fonts vianext/font. - HTTP client - Axios 1.13 for both REST and GraphQL calls.
- Tooling - ESLint 9 w/
eslint-config-next, Tailwind/PostCSS dependencies (not currently activated), and TypeScript project references viatsconfig.json. - Fonts & Icons -
next/fontfor Inter + New Rocker, Font Awesome CDN for icons.
Local Development
Prerequisites
- Node.js 20+ (recommended for Next.js 16)
- npm (ships with Node)
Setup & Scripts
npm install # install dependencies
npm run dev # start development server on http://localhost:3000
npm run build # production build
npm run start # serve production build
npm run lint # lint the codebase
Environment Variables
Create a .env.local file if you need authenticated trace.moe access:
NEXT_PUBLIC_TRACE_KEY=your_trace_moe_key
# or NEXT_PUBLIC_API_KEY / API_KEY - any of the three keys will be picked up
All variables are read client-side, so prefer the NEXT_PUBLIC_* names.
Usage Workflow
- Launch the dev server and open the root page.
- Provide an image:
- Paste a URL into the field or press
ctrl/cmd + vdirectly on the page. - Drag an image file anywhere in the window.
- Click the folder button to browse for a screenshot.
- Paste a URL into the field or press
- Watch the status text for progress (“Contacting trace.moe…”, “Fetching anime details…”).
- After a match is found, you are redirected to
/preview, where you can:- View the static frame or auto-playing clip (toggle sound with the speaker button).
- Read the AniList synopsis, score, and metadata.
- Jump to the AniList page via the action link.
- Use “new search” to return to the landing page; the previous result stays cached until you run another query or clear session storage.
Accessibility & UX Notes
- Keyboard access is preserved via semantic
<button>s and<input>s; drag indicators (styles.screenDrag) provide visual feedback. - Theme data attributes plus
color-schemeupdates ensure form controls adapt to each palette. - Errors such as invalid URLs or unsupported file types are surfaced immediately in-line.
License
No explicit license file or license entry is present in package.json. Until a license is added, the project should be treated as all rights reserved and contributions or redistribution should be cleared with the repository owner.