11 marca 2025 (updated: 11 marca 2025)
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.
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.
Na początek stwórzmy podstawowy projekt z Next.js:
npx create-next-app your-app-name
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
Gdy przejdziesz do http://localhost:3000 powinieneś zobaczyć stronę „Hello world” w 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.
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.
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’.
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.
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.
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ę”
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.
Możesz dodać nową kolumnę, naciskając „+” obok ostatniej nazwy kolumny lub usunąć, klikając prawym przyciskiem myszy. Potrzebujemy następujących kolumn:
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
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.
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.
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:
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.
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.
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.
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.
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)!
11 marca 2025 • Maria Pradiuszyk
11 marca 2025 • Maria Pradiuszyk