
Tworzenie aplikacji do generowania obrazów z Next.js i Hugging Face
Aplikacja jest efektem poszukiwania przeze mnie nowego alternatywnego stack’u technologicznego. Do tej pory korzystałem głównie z czystego HTML / SCSS, JS + jego mniejsze biblioteki do konkretnych elementów (slidery, animacje), następnie WordPress + ACV autorskie rozwiązania szablonów. Czasami jakiś framework typu Bootstrap Thailwind. Przy pomocy AI stworzyłem kilka koncepcji rozwiązań dla wdrożenia prostej aplikacji generującej zdjęcia z prompt’ów tekstowych, korzystające z bezpłatnych bibliotek i rozwiązań. Wstępne pomysły na stack technologiczny:
WordPress + Headless CMS + Frontend Framework (Z racji mojej bardzo dobrej znajomości WordPress’a)
Fullstack JavaScript (Node.js + Next.js/Vue/Nuxt.js)
Python + Django/FastAPI + AI/ML
Laravel + Vue/Nuxt.js (PHP + JavaScript)
Low-code/No-code
Tworzenie aplikacji do generowania obrazów z Next.js i Hugging Face
Część 1: Przygotowanie projektu
1.1. Wymagania wstępne
Zanim zaczniemy, upewnij się, że masz zainstalowane:
- Node.js (wersja LTS) – możesz pobrać ze strony https://nodejs.org/
- Edytor kodu (polecam Visual Studio Code)
Aby sprawdzić, czy Node.js jest poprawnie zainstalowany, otwórz terminal i wpisz:
node --version
npm --version
Obie komendy powinny wyświetlić numery wersji, np. v18.17.0
i 9.6.7
.
1.2. Tworzenie nowego projektu Next.js
- Otwórz terminal i przejdź do miejsca, gdzie chcesz utworzyć projekt:
mkdir prompt-image-generator
cd prompt-image-generator
- Zainicjuj nowy projekt Next.js:
npx create-next-app@latest .
- Podczas procesu instalacji, odpowiedz na pytania zgodnie z poniższymi ustawieniami:
Would you like to use TypeScript? → No
Would you like to use ESLint? → Yes
Would you like to use Tailwind CSS? → No
Would you like to use `src/` directory? → No
Would you like to use App Router? → Yes
Would you like to customize the default import alias (@/*)? → Yes
1.3. Struktura początkowa projektu
Po instalacji, Next.js utworzy następującą strukturę katalogów:
prompt-image-generator/
├── app/
│ ├── favicon.ico
│ ├── globals.css
│ ├── layout.js
│ └── page.js
├── public/
├── .eslintrc.json
├── .gitignore
├── next.config.js
├── package.json
└── package-lock.json
1.4. Konfiguracja SCSS
- Zainstaluj wsparcie dla SCSS:
npm install sass
- Zmień nazwę pliku
app/globals.css
naapp/globals.scss
- Zaktualizuj import w
app/layout.js
:
import './globals.scss'
1.5. Podstawowa konfiguracja
- Oczyść zawartość
app/page.js
i zastąp ją podstawowym kodem:
export default function Home() {
return (
<main>
<h1>Generator Obrazów AI</h1>
</main>
);
}
- Zaktualizuj
app/layout.js
:
import './globals.scss'
export const metadata = {
title: 'Generator Obrazów AI',
description: 'Generowanie obrazów przy pomocy sztucznej inteligencji',
}
export default function RootLayout({ children }) {
return (
<html lang="pl">
<body>{children}</body>
</html>
)
}
- Utwórz podstawowe style w
app/globals.scss
:
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html,
body {
max-width: 100vw;
min-height: 100vh;
overflow-x: hidden;
font-family: system-ui, -apple-system, sans-serif;
}
main {
padding: 2rem;
max-width: 1200px;
margin: 0 auto;
}
h1 {
text-align: center;
margin-bottom: 2rem;
}
1.6. Uruchomienie aplikacji
- Uruchom serwer deweloperski:
npm run dev
- Otwórz przeglądarkę i przejdź pod adres: http://localhost:3000
Powinieneś zobaczyć prostą stronę z nagłówkiem „Generator Obrazów AI”.
Zrozumienie architektury Next.js
Podstawowa struktura aplikacji
Wyobraź sobie Next.js jak budynek, gdzie:
layout.js
to konstrukcja budynku i jego główne ścianypage.js
to poszczególne pokojeapp
to cały plan budynku
Layout.js – Główny szkielet aplikacji
javascriptCopy// app/layout.js
// Importujemy globalne style, które będą dostępne w całej aplikacji
import './globals.css'
// Metadata to informacje o naszej stronie dla przeglądarek i wyszukiwarek
export const metadata = {
title: 'Generator Obrazów AI',
description: 'Generowanie obrazów przy pomocy sztucznej inteligencji',
}
// RootLayout to główny komponent, który otacza wszystkie strony
// Jest jak szkielet budynku - każda strona będzie wyświetlana wewnątrz niego
// {children} to specjalny parametr, który reprezentuje zawartość poszczególnych stron
export default function RootLayout({ children }) {
return (
// Określamy język strony dla dostępności
<html lang="pl">
{/* body zawiera całą widoczną zawartość strony */}
<body>
{/* children to miejsce, gdzie będą wyświetlane poszczególne strony */}
{children}
</body>
</html>
)
}
Page.js – Strony aplikacji
javascriptCopy// app/page.js
// Komponent strony głównej
// Next.js automatycznie używa tego komponentu dla ścieżki '/'
export default function Home() {
return (
// main to główny kontener treści
<main>
<h1>Generator Obrazów AI</h1>
</main>
);
}
Jak to wszystko działa razem?
- System routingu (kierowania):
- Next.js używa systemu routingu opartego na folderach
- Każdy folder w
app
może zawierać plikpage.js
, który staje się nową stroną - Na przykład: Copy
app/ ├── page.js → dostępny pod '/' ├── gallery/ │ └── page.js → dostępny pod '/gallery' └── about/ └── page.js → dostępny pod '/about'
- Proces renderowania: Copy
Żądanie strony '/' ↓ Layout.js (szkielet) ↓ Page.js (zawartość) ↓ Finalna strona
- Przykład dodawania nowej strony:
javascriptCopy// app/gallery/page.js
export default function Gallery() {
return (
<main>
<h1>Galeria wygenerowanych obrazów</h1>
{/* Ta zawartość będzie automatycznie wstawiona w {children} w layout.js */}
</main>
);
}
Dlaczego tak to działa?
- Współdzielony layout:
- Dzięki
layout.js
nie musimy powtarzać kodu HTML na każdej stronie - Wszystkie strony dziedziczą ten sam układ, style i metadane
- Możemy łatwo zmienić wygląd całej aplikacji, modyfikując jeden plik
- Dzięki
- Automatyczne routing:
- System folderów jest intuicyjny – struktura folderów = struktura URL
- Nie musimy ręcznie definiować routów jak w tradycyjnych aplikacjach
- Next.js automatycznie optymalizuje ładowanie stron
- Komponenty stron:
- Każda strona to niezależny komponent React
- Możemy używać wspólnych komponentów między stronami
- Łatwo zarządzać stanem i logiką każdej strony osobno
Praktyczne zastosowanie
W naszej aplikacji do generowania obrazów:
Wszystko będzie działać w ramach jednego, spójnego interfejsu
layout.js
będzie zawierał wspólne elementy jak nawigacja czy stopka
page.js
będzie zawierał formularz generowania obrazów
Możemy dodać gallery/page.js
dla galerii wygenerowanych obrazów