A fast, focused collection of random generators for movies, games, restaurants, websites, drawing prompts, names, colors, passwords, and more.
randomeower.com · Quick start · Self-hosting · Internal API reference · Contributing
Randomeower turns open-ended choices into a quick result. Find something to watch, play, visit, draw, or name, or generate practical values such as passwords, colors, UUIDs, and IP addresses. Choose a generator, tune the options when you want to, and skip the endless search.
| Category | Generators | Data source |
|---|---|---|
| Entertainment | Random Movie, Random TV Show, Random Game | TMDB, IGDB |
| Discovery | Random Restaurant, Random Website, Random Country, Random Things to Draw | Tripadvisor, Google PSE, built-in data |
| Tools | Password, Phone Number, Color, IP Address, UUID | Generated in the browser |
| Names | Name, Team Name, Job Title | Built-in data |
Prerequisites: Node.js ≥ 22 and npm ≥ 10.
This is the quickest way to work on the interface. No backend credentials are needed:
git clone https://github.com/pkorolyshyn/randomeower.git
cd randomeower
npm install
npm run web:devThe frontend runs at http://localhost:3000. Data-backed generators use the
hosted Randomeower backend by default. Browser-only generators continue to run
entirely on the local machine. No frontend environment file or self-hosted API
is required for this mode.
The hosted backend may be used this way for personal development and evaluation of Randomeower. Other uses are covered by the hosted API policy.
Running your own API locally requires credentials belonging to the person or organization operating it:
cp api/.env.example api/.env
cp web/.env.example web/.env.local
npm run devCopy web/.env.example only when using your local API; its single setting points
the frontend to http://localhost:8080/api. Before starting, fill every required
value in api/.env. The API checks these values at startup even if only one
data-backed generator is being developed. The required services are TMDB for
movies and TV shows, IGDB/Twitch for games, Tripadvisor for restaurants, Google
Programmable Search for website discovery, and Zoho Mail for the contact form.
The root development command starts both the API and frontend.
This is an npm-workspaces monorepo with three workspaces:
randomeower/
├── web/ Next.js 16 (App Router) frontend
│ └── src/
│ ├── app/ Routes only - every page is a thin wrapper that wires a
│ │ feature component to metadata; (generators) and (info)
│ │ are route groups
│ ├── features/ One folder per feature: each generator, plus layout,
│ │ │ home, faq, legal, contact, about
│ │ └── generators/
│ │ ├── catalog/ Single source of truth for all generators
│ │ │ (paths, titles, ordering) with startup invariants
│ │ ├── components/ Shared generator UI (workspace, fields,
│ │ │ async states)
│ │ └── hooks/ useGeneratorRequest - loading/empty/error state
│ ├── shared/ Cross-feature infrastructure: http client, clipboard
│ │ hook, ui primitives, seo helpers, formatters
│ └── config/ Site identity, routes, fonts
├── api/ Express backend - a thin proxy that validates requests and talks to
│ │ TMDB, IGDB, Tripadvisor, and Google Programmable Search, keeping all
│ │ API keys server-side
│ ├── routes/ One validated route per endpoint
│ ├── services/ One client per upstream provider
│ ├── middleware/ Rate limiting and error normalization
│ └── lib/ Validation and error helpers
└── playwright/ Browser health checks for all generators
├── pages/ Page objects and test-id locators
├── workflows/ Reusable result verification
└── tests/web/ Generator health-check specifications
Generators that only need randomness (passwords, UUIDs, colors, names, …) run entirely in the browser. Generators backed by external data (movies, games, restaurants, websites) call the api workspace, which holds the secrets, validates input, applies a rate limit, and normalizes upstream errors into a single { error, code } shape.
No API configuration is required for frontend-only development. This section applies only when you run your own API instance.
The self-hosted API reads its environment from api/.env. Start from
api/.env.example and provide these credentials:
The frontend reads the local API URL from web/.env.local. Create that file by
copying web/.env.example only for self-hosted development.
If the file is absent, the frontend continues to use the hosted Randomeower API.
| Variable | Required | Where to get it |
|---|---|---|
MOVIES_API_KEY |
Yes | TMDB API Read Access Token (v4 auth) |
GAMES_CLIENT_ID, GAMES_CLIENT_SECRET |
Yes | Twitch developer app for IGDB |
GOOGLE_API_KEY, GOOGLE_API_ID |
Yes | An operator-owned Google Cloud key and Programmable Search Engine ID (cx). The Custom Search JSON API is closed to new customers and existing customers must transition by January 1, 2027. |
TRIPADVISOR_API_KEY |
Yes | Tripadvisor Content API |
ZOHO_USER, ZOHO_PASS |
Yes | Zoho Mail address and SMTP/app-specific password used by the contact form |
The API validates its required variables on startup and exits with a clear message if any are missing. Every self-hosted instance must use its own provider accounts and must follow the applicable provider terms. The hosted Randomeower credentials are never included in this repository. See Third-party services and content for the license and usage boundary.
All endpoints live under /api. POST bodies are JSON (max 32 KB). These
routes document the interface between the Randomeower frontend and backend;
they are not offered as a public developer API. The
hosted API policy applies to the
official deployment. Self-hosters may operate the MIT-licensed code with their
own keys, subject to each provider's terms.
| Method | Path | Body / params | Returns |
|---|---|---|---|
POST |
/api/searchMovies |
pageNumber (1–20), genres, releaseDate ([from|null, to] as YYYY-MM-DD), userScore ([0–10, 0–10]), runtime ([min, max] minutes) |
A random matching TMDB movie ID |
GET |
/api/getMovieDetails/:movieId |
- | TMDB movie details incl. videos and reviews |
POST |
/api/searchSeries |
pageNumber (1–20), genres, userScore ([0–10, 0–10]) |
A random matching TMDB series ID |
GET |
/api/getSeriesDetails/:seriesId |
- | TMDB series details incl. videos and reviews |
POST |
/api/searchGame |
genres (IGDB genre IDs), releaseDate ([unixFrom, unixTo] or []), userScore ([0–100, 0–100]), criticsScore ([0–100, 0–100]) |
A one-item array with a matching IGDB game, or [] |
POST |
/api/findRandomRestaurant |
city, country |
{ locationId } of a random Tripadvisor restaurant |
GET |
/api/getRestaurantDetails/:locationId |
- | Tripadvisor location details |
GET |
/api/searchPhotos/:locationId |
- | Tripadvisor photos for a location |
POST |
/api/getWebsite |
searchQuery (≤ 100 chars) |
A random website link from Google Programmable Search |
POST |
/api/sendEmail |
name (≤ 100 chars), email, message (≤ 5,000 chars) |
Sends the contact message through Zoho SMTP |
Failures always return JSON in one shape:
{ "error": "No data available for the given criteria", "code": "NO_RESULTS" }| Code | Status | Meaning |
|---|---|---|
INVALID_REQUEST |
400 | Request body or params failed validation |
NO_RESULTS |
400 | Nothing matched the given filters |
NOT_FOUND |
404 | Unknown route |
PAYLOAD_TOO_LARGE / INVALID_JSON |
413 / 400 | Malformed request body |
RATE_LIMITED |
429 | Per-IP rate limit exceeded (default 120 req/min) |
EMAIL_DELIVERY_FAILED |
502 | Zoho SMTP rejected or could not deliver the contact message |
UPSTREAM_REQUEST_FAILED / UPSTREAM_TIMEOUT |
502 / 504 | A data provider failed or timed out |
INTERNAL_ERROR |
500 | Anything unexpected |
- Register it in
web/src/features/generators/catalog/generatorCatalog.js(id, path, title, description, thumbnail, category, ordering). Invariant checks will fail fast on duplicates. - Create
web/src/features/generators/<name>/with the generator component, a*.utils.jsor*.api.jsfor the logic, and a<Name>Seo.jsxsection. - Add a thumbnail to
web/public/thumbnails/. - Create the route:
web/src/app/(generators)/<path>/page.jsxwiringGeneratorPage,createGeneratorMetadata, and your components. Useexport const dynamic = "force-dynamic"only if the page renders a random initial value. - If it needs server-side data, add a validated route under
api/routes/and a provider client underapi/services/.
The web and api workspaces use Vitest:
- web - component and unit tests with Testing Library on jsdom.
- api - endpoint tests with Supertest against the real Express app, with the outgoing HTTP client mocked, so the suite never contacts TMDB, IGDB, Tripadvisor, Google, or Zoho and consumes no API quota.
Run npm run test from the root, or target one workspace with
npm run test -w web / npm run test -w api. npm run test:coverage produces
coverage reports. The quality workflow lints and tests the web and API
workspaces, checks web formatting, and creates a production web build on every
push and pull request.
The playwright workspace contains browser health checks for all 15 generators.
With the target site already running, use npm run test:e2e or
npm run test:e2e:ui. Tests target http://localhost:3000 by default; set
PLAYWRIGHT_BASE_URL to use another deployment. A separate daily workflow runs
the checks against https://www.randomeower.com/, publishes the generator
status page to GitHub Pages, and uploads the full HTML report as a workflow
artifact. That workflow can also be started manually and is intentionally
separate from pull-request CI.
Both apps deploy independently (the live site runs them as two Vercel projects):
- web - a Next.js deployment with the
web/directory as the project root. Git-triggered deployments are intentionally disabled inweb/vercel.json; remove that setting in a fork to enable automatic Vercel deployments. - api - an Express app deployed as a Vercel serverless function via
api/vercel.json, with theapi/directory as the project root. Set the required provider credentials in the project settings.
Randomeower would be an empty shell without these providers:
- TMDB - movie and TV show data.
- IGDB - game data via the Twitch/IGDB API.
- Tripadvisor - restaurant listings, ratings, and photos.
- Google Programmable Search Engine - random website discovery.
- Shihori Obata - the drawing-prompt illustrations.
If you self-host, review each provider's terms - attribution requirements apply. The country-flag and drawing images are served from the project's public Cloudinary cloud, which a local copy of the frontend may use for personal development and evaluation; a production fork needs its own Cloudinary account and appropriately licensed assets. Full details are in THIRD_PARTY_NOTICES.md.
Bug reports, generator ideas, and pull requests are welcome. See CONTRIBUTING.md for setup, style, architecture guidelines, and project ideas, or SUPPORT.md for ways to get in touch.
MIT © 2023-2026 Pavlo Korolyshyn. The MIT license applies to original Randomeower source code and project documentation. It does not license third-party API content, provider marks, credentials, or separately credited assets.