11 marca 2025 (updated: 11 marca 2025)

Jak stworzyć prostą aplikację filmową podobną do IMDb w Next.js?

Chapters

      Podczas budowania aplikacji zazwyczaj oddziela się frontend od backendu. Co jeśli połączysz te części, korzystając z frameworka Next.js? Dowiedz się, jak stworzyć prostą platformę bazy danych filmów w Next.js.

      Co to jest Next.js?

      Next.js to framework stworzony przez Vercel. Jest oparty na React i służy do budowy aplikacji webowych. To rozwiązanie umożliwia korzystanie z renderowania po stronie serwera oraz statycznie generowanych stron. Zalety Next.js to wysoka wydajność, przyjazność dla SEO oraz wysokiej jakości dokumentacja. Dlatego jest używany przez niektóre z największych firm, takich jak Twitch, HBO i Vodafone.

      Zacznijmy od konfiguracji projektu Next.js

      Na początek stwórzmy podstawowy projekt z Next.js:

      npx create-next-app your-app-name

      uruchamianie projektu w Next.js

      Teraz powinieneś zobaczyć wygenerowany projekt Next.js. Sprawdźmy, czy działa. Przejdź do katalogu swojego projektu i uruchom aplikację, używając poniższego polecenia.

      yarn dev

      Jak stworzyć prostą aplikację „podobną do iMDB” w Next.js

      Gdy przejdziesz do http://localhost:3000 powinieneś zobaczyć stronę „Hello world” w Next.js.

      strona powitalna next.js

      Struktura projektu powinna wyglądać jak na poniższym obrazku. Katalog ‘public’ zawiera pliki statyczne, które Next.js będzie automatycznie serwować. ‘src’ to ‘nasze pliki’ (pliki, które dodajemy do projektu). W ‘pages’ znajdują się pliki, które Next.js wykorzystuje do routingu.

      struktura katalogów next.js

      Skonfiguruj ESlint i Prettier

      To jest odpowiedni moment, jeśli chcesz dodać jakąś konfigurację, która pomoże Ci w formatowaniu kodu i zapobiegnie popełnianiu błędów podczas implementacji. Na przykład, możesz dodać ESlint i Prettier. W dokumentacji Next.JS znajduje się całkiem dobry samouczek. Ten krok jest opcjonalny.

      Dodaj baseUrl i zrób porządki

      Na początek pozbędziemy się niepotrzebnych plików. Usuń src/pages/api, plik src/pages/_documents.tsx oraz src/styles/Home.module.css.

      W głównym katalogu w tsconfig.json w obrębie sekcji “compilerOptions” możemy dodać parametr:

      "baseUrl": "./src"

      Dzięki temu później możesz używać krótszych importów, jak ‘styles’ zamiast ‘../../styles’.

      Przejdź do pages/_app.tsx. Ten plik zawiera kod, który jest globalny dla naszej aplikacji. Zmień import stylów z

      import '@/styles/globals.css';

      na

      import 'styles/globals.css';

      Teraz przejdź do pliku src/pages/index.tsx - to jest nasz ekran startowy. Usuń cały boilerplate i zostaw tylko jeden tekst ‘Filmweb APP’.

      Dodaj tailwind do stylizacji

      Każdy chce mieć eleganckie aplikacje. Masz wiele możliwości, aby Twoja aplikacja wyglądała naprawdę ładnie. Dodawanie stylizacji jest całkowicie opcjonalne, ale… możesz na przykład użyć Tailwind.

      Przygotuj bazę danych Airtable

      Airtable to usługa w chmurze, która wygląda bardzo podobnie do Excela lub Google Sheets. Pod maską jest to relacyjna baza danych. Wiele osób słyszy słowo "baza danych" i mówi, że to trudne, i że nie wiedzą wystarczająco dużo, aby ją stworzyć. Airtable pomaga w tworzeniu prostych baz danych z intuicyjnym interfejsem GUI, który możesz udostępnić swoim współpracownikom. Dodatkowo dostępny jest darmowy plan.

      Zarejestruj się i przygotuj bazę danych

      Nasza aplikacja będzie korzystać z bazy danych Airtable, więc przed dodaniem widoków itp. musisz założyć konto na platformie Airtable.

      Po rejestracji możesz przygotować bazę danych. Na swoim pulpicie Airtable powinieneś zobaczyć widok podobny do tego na poniższym obrazku. Kliknij „Dodaj bazę”

      Airtable dasboard next.js

      Najpierw nazwijmy tę bazę „iMDB_APP” i ustawmy nazwę tabeli na „filmy”. Następnie edytuj kolumny, klikając dwukrotnie ich nazwy lub używając prawego przycisku myszy.

      tworzenie bazy danych w airtable

      Możesz dodać nową kolumnę, naciskając „+” obok ostatniej nazwy kolumny lub usunąć, klikając prawym przyciskiem myszy. Potrzebujemy następujących kolumn:

      • id - autonumeracja
      • title - tekst jednoliniowy
      • description - tekst długi
      • category - pojedynczy wybór z opcjami takimi jak komedia i fantasy. Możesz dodać więcej opcji, jeśli chcesz, ale prawdopodobnie lepszym rozwiązaniem byłoby dodanie innej tabeli dla kategorii - nie zrobimy tego w tym samouczku.
      • likesAmount - liczba w formacie całkowitym
      • createdAt - czas utworzenia w formacie 24-godzinnym (zostanie dodany automatycznie przy dodawaniu nowego rekordu)
      • updatedAt - czas ostatniej modyfikacji  w formacie 24-godzinnym (zostanie zaktualizowany automatycznie przy każdej aktualizacji rekordu)

      Po utworzeniu tych kolumn możesz dodać kilka filmów do swojej tabeli, aby mieć coś, co możesz pokazać w aplikacji. Upewnij się, że przynajmniej jeden film ma przynajmniej trzy polubienia, będziemy tego potrzebować później.

      Potrzebujemy identyfikatora bazy danych, więc wybierz „Pomoc”, a następnie „Dokumentacja API”. Powinieneś zobaczyć coś w stylu „ID tej bazy to …” i skopiować to ID. Utwórz plik env.local w głównym katalogu projektu i wstaw:

      AIRTABLE_DB=your_id

      Następnie jest klucz API. Przejdź do przeglądu konta i w sekcji „API” wybierz „Przejdź do centrum dewelopera”. Teraz wybierz „Tokeny dostępu osobistego” i utwórz nowy token. Następnie skopiuj go i dodaj do swojego pliku env:

      AIRTABLE_API_KEY=your_token

      Utwórz widok filmów w Next.js

      Podstawowy układ z nawigacją

      Musimy przygotować układ do nawigacji między stronami. W katalogu src/components/layout utwórz Layout.tsx. Przygotowałem podstawową przyklejoną nawigację opartą na dokumentacji Tailwind CSS.

      Przeniosłem stopkę do innego pliku, aby było to bardziej przejrzyste, więc w katalogu layout utwórz plik Footer.tsx.

      Dodaj bibliotekę Airtable i konfigurację

      Wcześniej stworzyliśmy zmienne środowiskowe. Chcemy je wykorzystać i pokazać filmy z naszej bazy danych. Następnym krokiem będzie dodanie biblioteki Airtable. 

      yarn add airtable

      Teraz musimy dodać trochę konfiguracji, aby móc połączyć się z naszą bazą danych. Utwórz src/services/airtableClient.ts i umieść w nim następujący kod. Zauważ, że używamy tutaj zmiennych środowiskowych.

      Pobierz polecane filmy

      To czas, aby użyć wcześniej przygotowanego klienta. Ale przed tym dodajmy interfejs movieDto, aby mieć odpowiednie typy wszędzie. Utwórz plik movie.dto.ts w folderze src/interfaces/movie i umieść atrybuty filmu.

      Chcemy pokazać tylko polecane filmy na stronie głównej (te, które mają 3 polubienia lub więcej). Pomysł polega na tym, aby pobrać pewną ilość rekordów z tabeli „movies”, posortować je i przefiltrować według liczby polubień.

      Zmodyfikujmy stronę główną aplikacji, aby pokazywała polecane filmy. Użyjemy metody getStaticProps. Zostanie to zrealizowane w fazie budowy projektu. Chcielibyśmy pobrać rekordy z naszej bazy danych Airtable.

      Jak widać, zwracamy pewne propsy i filmy z metody getStaticProps. Teraz chcielibyśmy przekazać ten prop do naszego komponentu i renderować listę filmów.

      Przygotowałem podstawowy komponent karty z dokumentacji Tailwind z obrazkami z SVG Repo. Możesz go zmodyfikować według własnych potrzeb lub pominąć to i pokazać tylko tytuły filmów.

      Uruchommy aplikację i zobaczmy, jak działa i wygląda. Powinieneś zobaczyć coś takiego:

      Polecane filmy next.js

      Wygląda całkiem dobrze. Ale… Funkcja getStaticProps zostanie wykonana tylko raz, gdy generujemy statyczne podstrony dla naszego projektu. Kiedy dodamy nowe filmy, nie zobaczymy ich, dopóki projekt nie zostanie odbudowany. Aby temu zapobiec, możemy połączyć generację statycznych stron po stronie serwera z pobieraniem nowych filmów po stronie klienta. Użytkownik nie musi czekać na nic, aby to pokazać (generacja statyczna) i ma wszystko na bieżąco (z pobieraniem nowych filmów).

      Aby to zrobić, potrzebujemy prostego backendu. NExt.js traktuje jako backend każdy plik, który znajduje się w /pages/API -  nazywa się to API Routes. Utwórzmy index.ts w /src/pages/API. Na razie będziemy używać tylko żądań GET i zwrócimy 5 polecanych filmów.

      Będziemy używać tego punktu końcowego, aby dynamicznie pobierać polecane filmy po stronie klienta. W zasadzie, po otwarciu naszej strony, chcemy pokazać statycznie wygenerowane dane, ale także chcielibyśmy pobrać nowe filmy, aby wszystko było na bieżąco. Musimy zainstalować jeszcze jedną bibliotekę o nazwie SWR.

      yarn add swr

      Użyjmy hooka SWR. Pierwszym parametrem jest klucz, adres URL do naszego punktu końcowego API, następnie funkcja odpowiedzialna za wykonywanie żądań, a ostatnim jest konfiguracja (przekazywanie domyślnych danych itp.). Funkcję fetcher można zadeklarować w tym pliku lub wyeksportować z utils, aby była bardziej wielokrotnego użytku.

      Po tym możesz przejść do bazy danych Airtable, dodać filmy, zmienić liczbę polubień i sprawdzić, czy widzisz zaktualizowany widok po powrocie do aplikacji.

      Pobierz filmy zyskujące na popularności

      Po wyświetleniu rekomendowanych filmów, chcielibyśmy również pokazać te filmy, które zyskują na popularności. Wewnątrz /services/movies dodajmy plik getGainingPopularityMovies.ts. Wygląda to bardzo podobnie do pobierania rekomendowanych filmów, ale z innym filtrowaniem i sortowaniem.

      Teraz musimy stworzyć nową stronę. Dodaj gaining-popularity.tsx do /src/pages i skopiuj ich zawartość z index.tsx. Next.js wie, że wszystko wewnątrz katalogu strony jest używane do routingu. Jedyna rzecz, o której musisz pamiętać, to odpowiednie nazewnictwo plików (nazwa pliku = trasa). Przejdź do przeglądarki i sprawdź, czy przełączanie zakładek działa. 

      Mamy dwie działające zakładki, ale z tą samą zawartością. Zmodyfikujmy moviesHandler - gdy dodamy zapytanie “gainingPopularity”, handler zwróci filmy zyskujące na popularności, a w przeciwnym przypadku zwróci rekomendowane filmy.

      W gaining-popularity.tsx użyj funkcji getGainingPopularityMovies zamiast pobierania rekomendowanych filmów. Co więcej, musimy dodać parametr zapytania toxi. 

      Utwórz prosty formularz do dodawania filmu

      Teraz stwórzmy prosty formularz, abyśmy mogli dodać nowe filmy. Zacznij od stworzenia formularza z tytułem, opisem i kategorią. Dodaj plik new.tsx w folderze src/pages/movies. Nasz formularz będzie dostępny pod adresem /movies/new.

      Po pomyślnym utworzeniu filmu wyświetlimy informacje o jego sukcesie na osobnym ekranie. Tak więc zasadniczo przekierujemy użytkownika na trasę /movies/created.

      To jest moment, w którym musimy sprawić, aby nasz formularz działał. Zacznijmy od dodania biblioteki Zod, która pomoże nam w walidacji żądania po stronie backendu.

      yarn add zod

      Najpierw dodajmy schemat do tworzenia obiektów filmowych. Potrzebujemy danych z formularza -  tytułu, opisu i kategorii. Eksportuj również typ, będziemy go używać w widoku formularza.

      Następnie dodajmy createMovie.ts do katalogu src/services/movies i umieśćmy funkcję, która dodaje nowy film do bazy danych. Chcielibyśmy domyślnie przekazać 0 polubień i walidować filmy na podstawie wcześniej utworzonego schematu Zod. 

      Musimy również nieco zmodyfikować nasz handler API, aby nie zgłaszał wyjątku przy żądaniach POST. 

      Czas zaktualizować sam komponent formularza. Najpierw potrzebujemy jakiegoś ref, aby móc pobrać dane z formularza. Chcielibyśmy, aby przycisk miał inny tekst w przypadku przetwarzania formularza. Chcemy również wyświetlać błędy z backendu poniżej naszego przycisku. Najważniejszą funkcją jest handleSubmit. Tutaj pobieramy dane z pól i wysyłamy żądania do naszego API. Jeśli odpowiedź to 200, przekierowujemy użytkownika na wcześniej przygotowaną stronę, a w przeciwnym przypadku ustawiamy komunikat o błędzie. Możesz przenieść fetch i obsługę błędów do osobnego pliku i jakoś to opakować, aby było jaśniejsze. 

      Teraz możesz spróbować dodać nowy film, korzystając z formularza. Jeśli wypełnisz wszystkie dane, powinno to przekierować na trasę /movies/created. Aby przetestować walidację backendu, możesz dodać znak spacji w polu tytułu. Po naciśnięciu przycisku wyślij powinieneś zobaczyć błąd jak na poniższym obrazku.

      Prosta walidacja formularza

      Pokaż widok szczegółów filmu

      Musimy dodać widok szczegółów filmu. W tym przypadku chcielibyśmy przekierować użytkownika do /movies/1, movies/2 itd., gdzie numer to iD filmu. Next.js pobierze parametry z paska adresu przeglądarki, umieści je jako nazwy plików i wygeneruje te pliki. Nazywa się to dynamic routing. Stwórzmy plik o nazwie [id].tsx z podstawowym widokiem szczegółów. 

      Po przekierowaniu do widoku szczegółów filmu chcielibyśmy pobrać dane filmu z Airtable. Dodajmy plik getMovieById.ts w katalogu /src/services/movies i dodajmy tam trochę kodu do wyboru filmów według iD.

      Będziemy również potrzebować funkcji do pobierania filmów bez filtrowania. W src/services/movies dodaj jeszcze jeden plik o nazwie getMovies.ts.

      Wróć do [id].tsx i dodaj metody, które wygenerują strony i pobiorą dane filmu. Użyjemy funkcji getStaticPath, aby określić, które ścieżki chcemy wygenerować.  Ta metoda wymienia filmy i zwraca tablicę, która zostanie użyta przez Next.js do generowania stron. Każdy element tablicy musi zawierać params, a wewnątrz nich atrybut, który zostanie wstawiony jako nazwa pliku. W tym przypadku 'id', więc Next.js umieści to jako [id]. Musimy również ustawić fallback na true, aby dynamicznie generować strony. W getStaticPath pobieramy 10 filmów, iD od 1 do 10, użytkownicy przechodzą do /movies/13, a my jeszcze nie wygenerowaliśmy tej strony. Dzięki flagi fallback, Next.js daje nam możliwość obsługi tej sytuacji.

      Teraz mamy zbiór stron do wygenerowania, więc potrzebujemy kolejnej funkcji, aby uzyskać szczegóły każdego filmu. Dodajmy funkcję getStaticProps, która pobierze iD z każdej wygenerowanej ścieżki i na podstawie tego iD wywoła API, aby uzyskać dane filmu. Następnie zwrócimy film jako props i przekażemy go do komponentu MovieDetails.

      Przejdź do przeglądarki i zobacz strony szczegółów. Spróbuj zmienić iD w URL na iD, które nie zostało zwrócone podczas generowania zbioru ścieżek. Błąd w przeglądarce? Świetnie. Dzięki flagi fallback, Next.js może wygenerować tę stronę, ale w tym momencie nie pobiera danych.

      Naprawmy to. Rozwiązaniem jest sprawdzenie, czy mamy fallback i wyświetlenie jakichś loaderów, tekstu itp. gdy odpowiedź jest pozytywna. Next.js będzie miał czas na pobranie danych i wstrzyknięcie ich do komponentów.

      Podsumowanie

      Gratulacje! Twoja pierwsza aplikacja w Next.js jest gotowa. To naprawdę prosta aplikacja, ale jest wiele nowych rzeczy do nauczenia się. Możesz dodać więcej tabel, widoków i technik oraz rozwijać ten projekt, aby poszerzyć swoją wiedzę o Next.js. W następnej części możesz dowiedzieć się jak dodać prostą autoryzację użytkowników do swojego projektu.

      Możesz użyć Zod lub innej biblioteki, takiej jak Joi, do łatwej walidacji danych po stronie backendu Twojej aplikacji. Możesz użyć Tailwind lub Material UI do stylizacji, tak jak w aplikacji React. 

      Kiedy masz projekt z wieloma artykułami, szczegółami itp., możesz statycznie generować podstrony i pobierać dane w trakcie fazy budowy aplikacji. Dzięki temu możesz szybko pokazać treści użytkownikom, a następnie pobrać dane jeszcze raz, aby mieć wszystko na bieżąco.

      Next.js zdecydowanie powinien być brany pod uwagę przy rozpoczynaniu nowej aplikacji frontendowej (lub full stack)!

      Sprawdź także

      Agnieszka Łobocka

      React Native Developer

      Może to początek pięknej przyjaźni?

      Jesteśmy dostępni dla nowych projektów.

      Contact us