Smukły zestaw jest najnowszym z tego, co nazwałbym frameworkami aplikacji nowej generacji. To oczywiście tworzy rusztowanie dla aplikacji, z opartym na plikach routingiem, wdrażaniem i renderowaniem po stronie serwera, które Next robi od zawsze. Ale SvelteKit obsługuje również zagnieżdżone układy, mutacje serwera, które synchronizują dane na twojej stronie, i kilka innych drobiazgów, o których powiemy.
Ten post ma być wprowadzeniem na wysokim poziomie, aby, miejmy nadzieję, wzbudzić emocje u każdego, kto nigdy nie używał SvelteKit. To będzie spokojna wycieczka. Jeśli podoba ci się to, co widzisz, tzw pełna dokumentacja jest tutaj.
W pewnym sensie jest to trudny post do napisania. SvelteKit jest struktura aplikacji. Istnieje, aby pomóc Ci tworzyć… cóż, aplikacje. To utrudnia demonstrację. Nie jest możliwe zbudowanie całej aplikacji w poście na blogu. Zamiast tego użyjemy trochę naszej wyobraźni. Zbudujemy szkielet aplikacji, będziemy mieć kilka pustych symboli zastępczych interfejsu użytkownika i zakodowane na stałe dane statyczne. Celem nie jest zbudowanie rzeczywistej aplikacji, ale pokazanie, jak działają ruchome elementy SvelteKit, abyś mógł zbudować własną aplikację.
W tym celu zbudujemy jako przykład wypróbowaną i prawdziwą aplikację To-Do. Ale nie martw się, będzie to o wiele, wiele więcej o zobaczeniu, jak działa SvelteKit, niż o stworzeniu kolejnej aplikacji To-Do.
Kod do wszystkiego w tym poście to dostępne na GitHubie. Ten projekt też rozmieszczone na Vercel na demo na żywo.
Tworzę Twój projekt
Uruchomienie nowego projektu SvelteKit jest dość proste. Biegać npm create your-app-name
w terminalu i odpowiedz na pytania. Pamiętaj, aby wybrać „Skeleton Project”, ale poza tym dokonaj dowolnych wyborów dla TypeScript, ESLint itp.
Po utworzeniu projektu uruchom npm i
i npm run dev
i serwer deweloperski powinien zacząć działać. Odpalić localhost:5173
w przeglądarce, a otrzymasz stronę zastępczą dla aplikacji szkieletowej.
Routing podstawowy
Wskazówka routes
folder pod src
. To zawiera kod dla wszystkich naszych tras. Jest już +page.svelte
tam plik z treścią dla katalogu głównego /
trasa. Bez względu na to, gdzie jesteś w hierarchii plików, rzeczywista strona dla tej ścieżki zawsze ma nazwę +page.svelte
. Mając to na uwadze, stwórzmy strony dla /list
, /details
, /admin/user-settings
i admin/paid-status
, a także dodaj tekst zastępczy dla każdej strony.
Twój układ plików powinien wyglądać mniej więcej tak:
Powinieneś być w stanie nawigować, zmieniając ścieżki URL w pasku adresu przeglądarki.
układy
Będziemy potrzebować linków nawigacyjnych w naszej aplikacji, ale z pewnością nie chcemy kopiować ich znaczników na każdej tworzonej przez nas stronie. Stwórzmy więc a +layout.svelte
plik w katalogu głównym naszego routes
folder, który SvelteKit będzie traktował jako globalny szablon dla wszystkich stron. Dodajmy do tego trochę treści:
<nav> <ul> <li> <a href="/pl/">Home</a> </li> <li> <a href="/pl/list">To-Do list</a> </li> <li> <a href="/pl/admin/paid-status">Account status</a> </li> <li> <a href="/pl/admin/user-settings">User settings</a> </li> </ul>
</nav> <slot /> <style> nav { background-color: beige; } nav ul { display: flex; } li { list-style: none; margin: 15px; } a { text-decoration: none; color: black; }
</style>
Trochę podstawowej nawigacji z kilkoma podstawowymi stylami. Szczególne znaczenie ma tzw <slot />
etykietka. To jest nie gniazdo, którego używasz z komponentami sieciowymi i shadow DOM, a raczej funkcję Svelte wskazującą, gdzie umieścić nasze treści. Podczas renderowania strony zawartość strony wsunie się w miejsce, w którym znajduje się miejsce.
A teraz mamy trochę nawigacji! Nie wygramy żadnych konkursów projektowych, ale nie próbujemy.
Układy zagnieżdżone
Co by było, gdybyśmy chcieli, aby wszystkie nasze strony administracyjne odziedziczyły właśnie zbudowany przez nas normalny układ, ale także miały pewne cechy wspólne dla wszystkich stron administracyjnych (ale tylko dla stron administracyjnych)? Nie ma problemu, dodajemy kolejne +layout.svelte
plik w naszym katalogu głównym admin
katalog, który będzie dziedziczony przez wszystko, co znajduje się pod nim. Zróbmy to i dodajmy tę treść:
<div>This is an admin page</div> <slot /> <style> div { padding: 15px; margin: 10px 0; background-color: red; color: white; }
</style>
Dodajemy czerwony baner wskazujący, że jest to strona administracyjna, a następnie, tak jak poprzednio, a <slot />
oznaczające, gdzie chcemy, aby treść naszej strony się znalazła.
Nasz układ główny sprzed renderowania. Wewnątrz układu głównego znajduje się a <slot />
etykietka. Zawartość zagnieżdżonego układu trafia do układu głównego <slot />
. I wreszcie, zagnieżdżony układ definiuje swój własny <slot />
, do którego renderowana jest zawartość strony.
Jeśli przejdziesz do stron administracyjnych, powinieneś zobaczyć nowy czerwony baner:
Definiowanie naszych danych
OK, wyrenderujmy niektóre rzeczywiste dane — lub przynajmniej zobaczmy, jak możemy renderować niektóre rzeczywiste dane. Istnieje sto sposobów tworzenia bazy danych i łączenia się z nią. Ten post dotyczy jednak SvelteKit, a nie zarządzania DynamoDB, więc zamiast tego „załadujemy” trochę danych statycznych. Ale do odczytu i aktualizacji będziemy używać tych samych maszyn, których używałbyś do prawdziwych danych. Aby uzyskać prawdziwą aplikację internetową, zamień funkcje zwracające dane statyczne na funkcje łączące i wysyłające zapytania do dowolnej bazy danych, z której akurat korzystasz.
Stwórzmy prosty moduł w lib/data/todoData.ts
który zwraca niektóre dane statyczne wraz ze sztucznymi opóźnieniami w celu symulacji prawdziwych zapytań. Zobaczysz to lib
folder zaimportowany gdzie indziej przez $lib
. Jest to funkcja SvelteKit dla tego konkretnego folderu i możesz nawet dodaj własne aliasy.
let todos = [ { id: 1, title: "Write SvelteKit intro blog post", assigned: "Adam", tags: [1] }, { id: 2, title: "Write SvelteKit advanced data loading blog post", assigned: "Adam", tags: [1] }, { id: 3, title: "Prepare RenderATL talk", assigned: "Adam", tags: [2] }, { id: 4, title: "Fix all SvelteKit bugs", assigned: "Rich", tags: [3] }, { id: 5, title: "Edit Adam's blog posts", assigned: "Geoff", tags: [4] },
]; let tags = [ { id: 1, name: "SvelteKit Content", color: "ded" }, { id: 2, name: "Conferences", color: "purple" }, { id: 3, name: "SvelteKit Development", color: "pink" }, { id: 4, name: "CSS-Tricks Admin", color: "blue" },
]; export const wait = async amount => new Promise(res => setTimeout(res, amount ?? 100)); export async function getTodos() { await wait(); return todos;
} export async function getTags() { await wait(); return tags.reduce((lookup, tag) => { lookup[tag.id] = tag; return lookup; }, {});
} export async function getTodo(id) { return todos.find(t => t.id == id);
}
Funkcja zwracająca płaską tablicę naszych zadań do wykonania, wyszukiwanie naszych tagów oraz funkcja pobierania pojedynczego zadania do wykonania (tego ostatniego użyjemy na naszej stronie Szczegóły).
Ładowanie naszych danych
W jaki sposób umieszczamy te dane na naszych stronach Svelte? Istnieje wiele sposobów, ale na razie utwórzmy plik +page.server.js
plik w naszym list
folder i umieść w nim tę zawartość:
import { getTodos, getTags } from "$lib/data/todoData"; export function load() { const todos = getTodos(); const tags = getTags(); return { todos, tags, };
}
Zdefiniowaliśmy load()
funkcja, która pobiera dane potrzebne dla strony. Zauważ, że jesteśmy nie await
-ing dzwoni do nas getTodos
i getTags
funkcje asynchroniczne. Spowodowałoby to utworzenie wodospadu ładowania danych, gdybyśmy czekali, aż nasze zadania do wykonania pojawią się przed załadowaniem naszych tagów. Zamiast tego zwracamy surowe obietnice z load
, a SvelteKit wykona niezbędną pracę await
Im.
Jak więc uzyskać dostęp do tych danych z naszego komponentu strony? SvelteKit zapewnia data
prop dla naszego komponentu z danymi na jego temat. Uzyskamy dostęp do naszych rzeczy do zrobienia i tagów z niego za pomocą zadanie reaktywne.
Nasz komponent strony z listą wygląda teraz tak.
<script> export let data; $: ({ todo, tags } = data);
</script> <table cellspacing="10" cellpadding="10"> <thead> <tr> <th>Task</th> <th>Tags</th> <th>Assigned</th> </tr> </thead> <tbody> {#each todos as t} <tr> <td>{t.title}</td> <td>{t.tags.map((id) => tags[id].name).join(', ')}</td> <td>{t.assigned}</td> </tr> {/each} </tbody>
</table> <style> th { text-align: left; }
</style>
A to powinno renderować nasze rzeczy do zrobienia!
Grupy układów
Zanim przejdziemy do strony Szczegóły i zmutujemy dane, rzućmy okiem na naprawdę fajną funkcję SvelteKit: grupy układów. Widzieliśmy już zagnieżdżone układy dla wszystkich stron administracyjnych, ale co by było, gdybyśmy chcieli udostępnić układ między dowolnymi stronami na tym samym poziomie naszego systemu plików? W szczególności, co by się stało, gdybyśmy chcieli udostępnić układ tylko między naszą stroną listy a naszą stroną szczegółów? Mamy już globalny układ na tym poziomie. Zamiast tego możemy utworzyć nowy katalog, ale z nazwą w nawiasach, taką jak ta:
Mamy teraz grupę układu, która obejmuje nasze strony Lista i Szczegóły. Nazwałem to (todo-management)
ale możesz nazwać to jak chcesz. Żeby było jasne, ta nazwa będzie nie wpływają na adresy URL stron wewnątrz grupy układów. Adresy URL pozostaną takie same; grupy układów umożliwiają dodawanie współdzielonych układów do stron, tak aby wszystkie nie obejmowały całego katalogu w routes
.
We mógłby dodaj +layout.svelte
plik i trochę głupie <div>
baner z napisem „Hej, zarządzamy zadaniami”. Ale zróbmy coś ciekawszego. Układy mogą definiować load()
funkcje w celu dostarczenia danych dla wszystkich tras pod nimi. Użyjmy tej funkcji do załadowania naszych tagów — ponieważ będziemy używać naszych tagów w naszym details
strona — oprócz list
stronę, którą już mamy.
W rzeczywistości zmuszanie grupy układu do dostarczenia pojedynczego fragmentu danych prawie na pewno nie jest tego warte; lepiej powielić te dane w pliku load()
funkcja dla każdej strony. Ale w tym poście będzie to wymówka, której potrzebujemy, aby zobaczyć nową funkcję SvelteKit!
Najpierw przejdźmy do naszego list
strony +page.server.js
plik i usuń z niego znaczniki.
import { getTodos, getTags } from "$lib/data/todoData"; export function load() { const todos = getTodos(); return { todos, };
}
Nasza strona z listą powinna teraz generować błąd, ponieważ go nie ma tags
obiekt. Naprawmy to, dodając a +layout.server.js
w naszej grupie układu, a następnie zdefiniuj plik load()
funkcja ładująca nasze tagi.
import { getTags } from "$lib/data/todoData"; export function load() { const tags = getTags(); return { tags, };
}
I tak po prostu nasza strona z listą jest ponownie renderowana!
Ładujemy dane z wielu lokalizacji
Postawmy dobry punkt na to, co się tutaj dzieje:
- Zdefiniowaliśmy
load()
funkcja dla naszej grupy układu, którą umieściliśmy+layout.server.js
. - Daje to dane dot cała kolekcja stron obsługiwanych przez układ — co w tym przypadku oznacza nasze strony Lista i Szczegóły.
- Nasza strona z listą definiuje również a
load()
funkcja, która się w nim znajduje+page.server.js
plik. - SvelteKit wykonuje ciężką pracę polegającą na pobieraniu wyników z tych źródeł danych, łączeniu ich razem i udostępnianiu obu w
data
.
Nasza strona Szczegóły
Użyjemy naszej strony Szczegóły, aby edytować element do zrobienia. Najpierw dodajmy do tabeli na naszej stronie Lista kolumnę, która prowadzi do strony Szczegóły z identyfikatorem zadania do wykonania w ciągu zapytania.
<td><a href="/pl/details?id={t.id}">Edit</a></td>
Teraz zbudujmy naszą stronę Szczegóły. Najpierw dodamy moduł ładujący, który pobierze element do zrobienia, który edytujemy. Stwórz +page.server.js
in /details
, o tej treści:
import { getTodo, updateTodo, wait } from "$lib/data/todoData"; export function load({ url }) { const id = url.searchParams.get("id"); console.log(id); const todo = getTodo(id); return { todo, };
}
Nasza ładowarka jest wyposażona w url
właściwość, z której możemy pobrać wartości ciągu zapytania. Ułatwia to wyszukiwanie elementu do zrobienia, który edytujemy. Wyrenderujmy to zadanie wraz z funkcjonalnością do jego edycji.
SvelteKit ma wspaniałe wbudowane możliwości mutacji, o ile używasz formularzy. Pamiętasz formularze? Oto nasza strona Szczegóły. Pominąłem style dla zwięzłości.
<script> import { enhance } from "$app/forms"; export let data; $: ({ todo, tags } = data); $: currentTags = todo.tags.map(id => tags[id]);
</script> <form use:enhance method="post" action="?/editTodo"> <input name="id" type="hidden" value="{todo.id}" /> <input name="title" value="{todo.title}" /> <div> {#each currentTags as tag} <span style="{`color:" ${tag.color};`}>{tag.name}</span> {/each} </div> <button>Save</button>
</form>
Pobieramy tagi, tak jak poprzednio, z modułu ładującego naszej grupy układów i element do zrobienia z modułu ładującego naszą stronę. Chwytamy rzeczywistość tag
obiekty z listy identyfikatorów tagów do zrobienia, a następnie renderowanie wszystkiego. Tworzymy formularz z ukrytym wejściem dla ID i prawdziwym wejściem dla tytułu. Wyświetlamy tagi, a następnie udostępniamy przycisk do wysłania formularza.
Jeśli zauważyłeś use:enhance
, który po prostu mówi SvelteKit, aby użył progresywnego ulepszania i Ajax, aby przesłać nasz formularz. Prawdopodobnie zawsze będziesz tego używać.
Jak zapisujemy nasze zmiany?
Wskazówka action="?/editTodo"
atrybut w samym formularzu? To mówi nam, gdzie chcemy przesłać nasze edytowane dane. W naszym przypadku chcemy przesłać do an editTodo
"akcja."
Utwórzmy go, dodając następujące elementy do pliku +page.server.js
plik, który już mamy dla szczegółów (który obecnie ma plik load()
funkcja, aby pobrać nasze zadanie):
import { redirect } from "@sveltejs/kit"; // ... export const actions = { async editTodo({ request }) { const formData = await request.formData(); const id = formData.get("id"); const newTitle = formData.get("title"); await wait(250); updateTodo(id, newTitle); throw redirect(303, "/list"); },
};
Działania formularza dają nam a request
obiekt, który zapewnia dostęp do naszego formData
, który ma get
metoda dla naszych różnych pól formularza. Dodaliśmy to ukryte wejście dla wartości identyfikatora, abyśmy mogli pobrać je tutaj, aby wyszukać edytowany przez nas element do zrobienia. Symulujemy opóźnienie, nazywamy nowe updateTodo()
metody, a następnie przekieruj użytkownika z powrotem do /list
strona. The updateTodo()
metoda jedynie aktualizuje nasze dane statyczne; w prawdziwym życiu uruchomiłbyś jakąś aktualizację w dowolnym magazynie danych, którego używasz.
export async function updateTodo(id, newTitle) { const todo = todos.find(t => t.id == id); Object.assign(todo, { title: newTitle });
}
Wypróbujmy to. Najpierw przejdziemy do strony z listą:
Teraz kliknijmy przycisk Edytuj dla jednego z zadań do wykonania, aby wyświetlić stronę edycji /details
.
Dodamy nowy tytuł:
Teraz kliknij Zapisz. To powinno sprowadzić nas z powrotem do naszego /list
stronę z zastosowanym nowym tytułem zadania.
Jak pojawił się nowy tytuł? To było automatyczne. Po przekierowaniu do /list
stronie, SvelteKit automatycznie ponownie uruchomił wszystkie nasze programy ładujące, tak jak zrobiłby to niezależnie od tego. Jest to kluczowy postęp, jaki dają frameworki aplikacji nowej generacji, takie jak SvelteKit, Remix, Następny 13 zapewniać. Zamiast oferować wygodny sposób renderowania stron, a następnie życzyć powodzenia w pobieraniu dowolnych punktów końcowych, które mogą być potrzebne do aktualizacji danych, integrują mutację danych z ładowaniem danych, umożliwiając tym dwóm pracę w tandemie.
Kilka rzeczy, które możesz się zastanawiać…
Ta aktualizacja mutacji nie wydaje się zbyt imponująca. Ładowarki uruchomią się ponownie za każdym razem, gdy będziesz nawigować. Co by było, gdybyśmy nie dodali przekierowania w naszej akcji formularza, ale pozostali na bieżącej stronie? SvelteKit wykonałby aktualizację w akcji formularza, tak jak poprzednio, ale by to zrobił nadal ponownie uruchom wszystkie programy ładujące dla bieżącej strony, w tym programy ładujące w układzie strony.
Czy możemy mieć bardziej ukierunkowane sposoby unieważniania naszych danych? Na przykład nasze tagi nie były edytowane, więc w rzeczywistości nie chcielibyśmy ich ponownie sprawdzać. Tak, to, co ci pokazałem, to tylko domyślne zachowanie formularzy w SvelteKit. Możesz wyłączyć domyślne zachowanie przez zapewnienie oddzwonienia do use:enhance
. Następnie SvelteKit zapewnia instrukcję funkcje unieważniające.
Ładowanie danych przy każdej nawigacji jest potencjalnie kosztowne i niepotrzebne. Czy mogę buforować te dane, tak jak robię to za pomocą narzędzi takich jak react-query
? Tak, tylko inaczej. SvelteKit pozwala ustawić (a następnie szanować) nagłówki kontroli pamięci podręcznej, które już zapewnia sieć. W kolejnym poście omówię mechanizmy unieważniania pamięci podręcznej.
Wszystko, co zrobiliśmy w tym artykule, używa danych statycznych i modyfikuje wartości w pamięci. Jeśli chcesz przywrócić wszystko i zacząć od nowa, zatrzymaj i uruchom ponownie npm run dev
Proces węzła.
Zamykając
Ledwo zarysowaliśmy powierzchnię SvelteKit, ale mamy nadzieję, że widziałeś wystarczająco dużo, aby się tym ekscytować. Nie pamiętam, kiedy ostatnio tworzenie stron internetowych sprawiało mi tyle radości. Dzięki takim rzeczom, jak łączenie, routing, SSR i wdrażanie, które są obsługiwane od razu po wyjęciu z pudełka, spędzam więcej czasu na kodowaniu niż na konfigurowaniu.
Oto kilka dodatkowych zasobów, których możesz użyć jako kolejnych kroków w nauce SvelteKit:
- Dystrybucja treści i PR oparta na SEO. Uzyskaj wzmocnienie już dziś.
- Platoblockchain. Web3 Inteligencja Metaverse. Wzmocniona wiedza. Dostęp tutaj.
- Źródło: https://css-tricks.com/getting-started-with-sveltekit/
- 1
- 10
- 100
- 11
- 7
- 9
- 98
- a
- Zdolny
- O nas
- o tym
- dostęp
- Konto
- Działania
- działania
- Adam
- w dodatku
- dodatek
- adres
- Admin
- zaawansowany
- oddziaływać
- Wszystkie kategorie
- Pozwalać
- wzdłuż
- już
- zawsze
- ilość
- i
- Inne
- odpowiedź
- ktoś
- Aplikacja
- Zastosowanie
- aplikacje
- stosowany
- na około
- Szyk
- artykuł
- sztuczny
- przydzielony
- automatycznie
- automatycznie
- dostępny
- oczekiwać
- z powrotem
- tło
- transparent
- bar
- podstawowy
- zanim
- BEST
- Ulepsz Swój
- pomiędzy
- Bit
- Czarny
- Blog
- Najnowsze wpisy
- Niebieski
- Pudełko
- przynieść
- przeglądarka
- błędy
- budować
- wybudowany
- wbudowany
- przycisk
- Cache
- wezwanie
- Połączenia
- możliwości
- walizka
- na pewno
- wyzwanie
- wymiana pieniędzy
- jasny
- kod
- Kodowanie
- kolor
- Kolumna
- jak
- wspólny
- Konkursy
- składnik
- składniki
- konferencje
- Skontaktuj się
- Podłączanie
- Konsola
- zawartość
- Wygodny
- mógłby
- Kurs
- pokrycie
- Okładki
- Stwórz
- stworzony
- Tworzenie
- Aktualny
- Obecnie
- dane
- Baza danych
- Domyślnie
- Definiuje
- opóźnienie
- opóźnienia
- Wdrożenie
- Wnętrze
- detale
- dev
- oprogramowania
- ZROBIŁ
- Wyświetlacz
- Nie
- robi
- nie
- każdy
- gdzie indziej
- dość
- Cały
- całość
- błąd
- itp
- Parzyste
- Każdy
- wszystko
- przykład
- podniecony
- Podniecenie
- istnieje
- drogi
- eksport
- wykonalny
- Cecha
- kilka
- Łąka
- filet
- Akta
- W końcu
- w porządku
- natura
- i terminów, a
- Fix
- mieszkanie
- następujący
- na zawsze
- Nasz formularz
- format
- formularze
- znaleziono
- Ramy
- od
- pełny
- zabawa
- funkcjonować
- Funkcjonalność
- Funkcje
- otrzymać
- miejsce
- Dać
- Dający
- Globalne
- Go
- cel
- Goes
- będzie
- chwycić
- Zarządzanie
- Grupy
- zdarzyć
- Ciężko
- headers
- pomoc
- tutaj
- Ukryty
- hierarchia
- na wysokim szczeblu
- posiada
- Ufnie
- Poziomy
- W jaki sposób
- HTML
- HTTPS
- CHORY
- wyobraźnia
- importować
- znaczenie
- imponujący
- in
- Włącznie z
- początkowy
- wkład
- zamiast
- integrować
- ciekawy
- Wprowadzenie
- IT
- szt
- samo
- JAVASCRIPT
- Klawisz
- Nazwisko
- firmy
- układ
- nauka
- pozwala
- poziom
- Li
- życie
- lekki
- Prawdopodobnie
- linki
- Lista
- relacja na żywo
- załadować
- ładowarka
- załadunek
- masa
- długo
- Popatrz
- WYGLĄD
- wyszukiwania
- szczęście
- maszyny
- robić
- WYKONUJE
- Dokonywanie
- zarządzający
- podręcznik
- Margines
- Materia
- znaczy
- Pamięć
- jedynie
- połączenie
- metoda
- może
- nic
- Moduł
- jeszcze
- ruch
- przeniesienie
- wielokrotność
- Nazwa
- O imieniu
- nav
- Nawigacja
- Nawigacja
- niezbędny
- Potrzebować
- Nowości
- Następny
- węzeł
- normalna
- numer
- przedmiot
- obiekty
- ONE
- zamówienie
- Inne
- Inaczej
- własny
- szczególny
- ścieżka
- wykonać
- wybierać
- kawałek
- sztuk
- zastępczy
- plato
- Analiza danych Platona
- PlatoDane
- punkt
- Post
- Wiadomości
- potencjalnie
- Przygotować
- Problem
- wygląda tak
- produkować
- progresywny
- projekt
- obiecuje
- własność
- chroniony
- zapewniać
- zapewnia
- Ściąga
- położyć
- pytanie
- Surowy
- Czytaj
- real
- prawdziwe życie
- Rzeczywistość
- Czerwony
- przekierowanie
- Bez względu
- pozostawać
- pamiętać
- usunąć
- wykonanie
- renderuje
- zażądać
- Zasoby
- Efekt
- powrót
- powrót
- powraca
- przywrócić
- Bogaty
- korzeń
- Trasa
- trasy
- run
- bieganie
- taki sam
- Zapisz
- widzenie
- służy
- zestaw
- Shadow
- Share
- shared
- powinien
- pokazać
- Prosty
- po prostu
- ponieważ
- pojedynczy
- suwak
- So
- kilka
- coś
- Źródła
- wydać
- początek
- rozpoczęty
- został
- Cel
- Stop
- Zatwierdź
- podpory
- Powierzchnia
- system
- stół
- TAG
- Brać
- biorąc
- Mówić
- Tandem
- ukierunkowane
- mówi
- szablon
- terminal
- Połączenia
- rzeczy
- poprzez
- czas
- Tytuł
- do
- razem
- także
- narzędzia
- Wycieczka
- leczyć
- prawdziwy
- SKRĘCAĆ
- Maszynopis
- ui
- dla
- Aktualizacja
- Nowości
- URL
- us
- posługiwać się
- Użytkownik
- wartość
- Wartości
- różnorodny
- przez
- Zobacz i wysłuchaj
- czekać
- poszukiwany
- sposoby
- sieć
- komponenty sieciowe
- Tworzenie stron internetowych
- Co
- który
- biały
- będzie
- wygrać
- bez
- wspaniale
- Praca
- działa
- wartość
- by
- napisać
- You
- Twój
- zefirnet