Skip to content

pkorolyshyn/randomeower

Repository files navigation

Randomeower project cover

A fast, focused collection of random generators for movies, games, restaurants, websites, drawing prompts, names, colors, passwords, and more.

Live site Quality checks status Daily Playwright status License: MIT Node >= 22 Next.js 16 React 19 Express 4 PRs welcome

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.

✨ Generators

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

🚀 Quick start

Prerequisites: Node.js ≥ 22 and npm ≥ 10.

Frontend only

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:dev

The 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.

Self-host the API locally

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 dev

Copy 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.

🏗 Architecture

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.

🔧 Self-hosted API configuration

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.

🔌 Internal API reference

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

🧩 Adding a generator

  1. Register it in web/src/features/generators/catalog/generatorCatalog.js (id, path, title, description, thumbnail, category, ordering). Invariant checks will fail fast on duplicates.
  2. Create web/src/features/generators/<name>/ with the generator component, a *.utils.js or *.api.js for the logic, and a <Name>Seo.jsx section.
  3. Add a thumbnail to web/public/thumbnails/.
  4. Create the route: web/src/app/(generators)/<path>/page.jsx wiring GeneratorPage, createGeneratorMetadata, and your components. Use export const dynamic = "force-dynamic" only if the page renders a random initial value.
  5. If it needs server-side data, add a validated route under api/routes/ and a provider client under api/services/.

🧪 Testing

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.

🚢 Deployment

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 in web/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 the api/ directory as the project root. Set the required provider credentials in the project settings.

🙏 Data sources and attribution

Randomeower would be an empty shell without these providers:

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.

🤝 Contributing

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.

📄 License

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.

About

Open-source discovery platform for finding something fun, useful, or unexpected in seconds.

Topics

Resources

Contributing

Stars

Watchers

Forks

Contributors

Languages