Movies and TV shows explorer with search, filters, and complete details integrated with The Movie Database (TMDB) API.
FyM is a modern web application to explore movies and TV shows catalog. Built with Next.js 16 and React 19, it uses the App Router for a Server Components-based architecture with hybrid rendering support.
- Content Exploration: Browse by categories (Trending, Popular, Top Rated, Upcoming, Now Playing)
- Multi-domain Search: Search movies, shows, and people simultaneously
- Complete Details: Extended info, credits, trailers, streaming providers
- Advanced Filtering: Genre filtering and custom sorting
- Collections: Movie collections viewing
- Responsive Design: Optimized for mobile and desktop
- Advanced UX: Loading skeletons, debounced search, auto-scroll in carousels
| Technology | Version | Purpose |
|---|---|---|
| Next.js | 16.2.1 | React Framework with App Router |
| React | 19.2.4 | UI Library |
| TypeScript | 5.x | Static Typing |
| Tailwind CSS | 4.x | Style Utilities |
| TMDB API | v3 | Data Source |
fym/
βββ public/ # Static assets
β βββ file.svg
β βββ globe.svg
β βββ next.svg
β βββ vercel.svg
β βββ window.svg
βββ src/
β βββ app/ # Next.js App Router
β β βββ layout.tsx # Root layout
β β βββ page.tsx # Home page
β β βββ globals.css # Global styles
β β βββ favicon.ico
β β βββ movies/ # Movies catalog
β β β βββ page.tsx
β β β βββ MoviesClient.tsx
β β β βββ loading.tsx
β β βββ series/ # TV Series catalog
β β β βββ page.tsx
β β β βββ SeriesClient.tsx
β β β βββ loading.tsx
β β βββ search/ # Search page
β β β βββ page.tsx
β β βββ movie/[id]/ # Movie details
β β β βββ page.tsx
β β βββ series/[id]/ # Series details
β β β βββ page.tsx
β β βββ collection/[id]/ # Collection details
β β βββ page.tsx
β βββ components/ # React Components
β β βββ HeroBanner.tsx
β β βββ HeroBannerWrapper.tsx
β β βββ MovieCard.tsx
β β βββ MovieFilters.tsx
β β βββ MovieGrid.tsx
β β βββ MovieRow.tsx
β β βββ Navbar.tsx
β β βββ SearchSkeleton.tsx
β βββ hooks/ # Custom React Hooks
β β βββ useSearch.ts
β β βββ useDebounce.ts
οΏ½οΏ½οΏ½ βββ lib/ # Utilities and business logic
β β βββ api/
β β βββ client.ts # API Client + TypeScript interfaces
β β βββ config.ts # Configuration and endpoints
β β βββ index.ts # Exports
β βββ types/ # TypeScript types
β βββ movie.ts
βββ .env.local # Environment variables
βββ eslint.config.mjs # ESLint configuration
βββ next.config.ts # Next.js configuration
βββ package.json
βββ postcss.config.mjs # PostCSS configuration
βββ tailwind.config.ts # Tailwind configuration
βββ tsconfig.json # TypeScript configuration
- Node.js 18.x or higher
- NPM, Yarn, PNPM or Bun
- Clone the repository
git clone <repository-url>
cd fym- Install dependencies
npm install
# or
yarn install
# or
pnpm install
# or
bun install- Configure environment variables
Create a .env.local file in the project root:
NEXT_PUBLIC_TMDB_API_KEY=your_tmdb_api_key
NEXT_PUBLIC_OMDB_API_KEY=your_omdb_api_key # OptionalTo get a TMDB API key, register at themoviedb.org.
- Run the development server
npm run dev- Open in browser
Navigate to http://localhost:3000
| Script | Description |
|---|---|
npm run dev |
Starts the development server |
npm run build |
Builds the application for production |
npm run start |
Starts the production server |
npm run lint |
Runs ESLint |
Main pages use Server Components for direct server-side data fetching:
// src/app/page.tsx
async function getData() {
const [trending, popular, topRated] = await Promise.all([
apiClient.getTrending("movie"),
apiClient.getMoviePopular(),
apiClient.getMovieTopRated(),
]);
return { trending, popular, topRated };
}Interactive components that require state or effects:
Navbar: Navigation with searchHeroBannerWrapper: Auto-scrolling carouselMovieRow: Carousels with auto-scrollMoviesClient/SeriesClient: Client-side state for filters and infinite scrollSearchSkeleton: Loading states
- useSearch: Hook for search with 500ms debounce and state management
- useDebounce: Utility to prevent excessive requests during typing
| Page | Strategy |
|---|---|
| Home | SSR with cache (revalidate: 3600s) |
| Movies/Series | Initial SSR + CSR for interaction |
| Search | CSR (client-side search) |
| Details | SSR with related data |
The project consumes The Movie Database API with the following implemented endpoints:
| Method | Endpoint | Description |
|---|---|---|
getTrending(mediaType) |
/trending/{mediaType}/week |
Trending content |
getMoviePopular(page) |
/movie/popular |
Popular movies |
getMovieTopRated(page) |
/movie/top_rated |
Top rated movies |
getMovieUpcoming(page) |
/movie/upcoming |
Upcoming movies |
getMovieNowPlaying(page) |
/movie/now_playing |
Now in theaters |
getMovieDetails(id) |
/movie/{id} |
Full details |
getMovieSimilar(id) |
/movie/{id}/similar |
Similar movies |
getMovieCredits(id) |
/movie/{id}/credits |
Cast and crew |
getMovieVideos(id) |
/movie/{id}/videos |
Trailers and clips |
getMovieWatchProviders(id) |
/movie/{id}/watch/providers |
Where to watch |
discoverMovies(genre, page, sortBy) |
/discover/movie |
Discover by genre |
| Method | Endpoint | Description |
|---|---|---|
getTvPopular(page) |
/tv/popular |
Popular TV shows |
getTvTopRated(page) |
/tv/top_rated |
Top rated TV shows |
getTvOnTheAir(page) |
/tv/on_the_air |
Currently airing |
getTvDetails(id) |
/tv/{id} |
Full details |
getTvSeasonDetails(id, season) |
/tv/{id}/season/{season} |
Season details |
| Method | Endpoint | Description |
|---|---|---|
searchMulti(query, page) |
/search/multi |
Global search |
searchMovies(query, page) |
/search/movie |
Search movies |
searchTvShows(query, page) |
/search/tv |
Search TV shows |
// src/lib/api/config.ts
export const IMAGE_SIZES = {
poster: { small: "w185", medium: "w342", large: "w500", original: "original" },
backdrop: { small: "w300", medium: "w780", large: "w1280", ultra: "original" },
profile: { small: "w45", medium: "w185", large: "h632", original: "original" },
} as const;| Variable | Required | Description |
|---|---|---|
NEXT_PUBLIC_TMDB_API_KEY |
β | TMDB API Key |
NEXT_PUBLIC_OMDB_API_KEY |
β | OMDB API Key (optional) |
Note: API keys in
.env.localare for development. For production, use secure environment variables on your hosting platform.
- Framework: Tailwind CSS 4 with PostCSS
- Theme: Dark with red accents
- Typography: Geist (sans/mono) + Rubik Glitch (brand)
- Effects: Backdrop blur, smooth transitions, hover states
| Color | Usage |
|---|---|
#1A1A1B |
Main background |
#FFFFFF |
Primary text |
#9CA3AF |
Secondary text |
#DC2626 (red-600) |
Accents, actions |
#EF4444 (red-500) |
Hover states |
- HeroBanner: Auto-scrolling carousel with background gradient
- MovieRow: Horizontal carousel with auto-scroll
- MovieGrid: Responsive card grid
- MovieCard: Card with poster, title and rating
- Navbar: Fixed navigation with search
- SearchSkeleton: Loading state skeletons
- MovieFilters: Genre and sorting filters
- Next.js - React framework
- React - UI library
- Tailwind CSS - Styling
- TMDB - Data provider
MIT License - Copyright (c) 2024
Permission is hereby granted, free of charge, to any person obtaining a copy of this software to deal in the Software without restriction.