SvelteKit adalah yang terbaru dari apa yang saya sebut kerangka kerja aplikasi generasi berikutnya. Itu, tentu saja, membangun aplikasi untuk Anda, dengan perutean berbasis file, penerapan, dan rendering sisi server yang telah dilakukan Next selamanya. Tapi SvelteKit juga mendukung tata letak bersarang, mutasi server yang menyinkronkan data di halaman Anda, dan beberapa fitur lain yang akan kami bahas.
Posting ini dimaksudkan sebagai pengantar tingkat tinggi untuk membangun kegembiraan bagi siapa saja yang belum pernah menggunakan SvelteKit. Ini akan menjadi tur yang santai. Jika Anda menyukai apa yang Anda lihat, the dokumen lengkap ada di sini.
Dalam beberapa hal ini adalah posting yang menantang untuk ditulis. SvelteKit adalah sebuah kerangka aplikasi. Itu ada untuk membantu Anda membangunโฆ yah, aplikasi. Itu membuatnya sulit untuk didemonstrasikan. Tidak mungkin membangun seluruh aplikasi dalam posting blog. Jadi sebagai gantinya, kita akan menggunakan sedikit imajinasi kita. Kami akan membangun kerangka aplikasi, memiliki beberapa placeholder UI kosong, dan data statis yang dikodekan keras. Tujuannya bukan untuk membangun aplikasi yang sebenarnya, tetapi untuk menunjukkan kepada Anda bagaimana potongan bergerak SvelteKit bekerja sehingga Anda dapat membangun aplikasi Anda sendiri.
Untuk itu, kami akan membangun aplikasi To-Do yang telah dicoba dan benar sebagai contoh. Tapi jangan khawatir, ini akan jauh lebih banyak tentang melihat cara kerja SvelteKit daripada membuat aplikasi To-Do lainnya.
Kode untuk semua yang ada di posting ini adalah tersedia di GitHub. Proyek ini juga digunakan di Vercel untuk demo langsung.
Membuat proyek Anda
Memutar proyek SvelteKit baru cukup sederhana. Lari npm create your-app-name
di terminal dan jawab pertanyaan petunjuknya. Pastikan untuk memilih "Proyek Skeleton" tetapi jika tidak, buat pilihan apa pun yang Anda inginkan untuk TypeScript, ESLint, dll.
Setelah proyek dibuat, jalankan npm i
dan npm run dev
dan server dev harus mulai berjalan. Semangat localhost:5173
di browser dan Anda akan mendapatkan halaman placeholder untuk aplikasi kerangka.
Perutean dasar
Perhatikan routes
folder di bawah src
. Itu memegang kode untuk semua rute kami. Sudah ada +page.svelte
file di sana dengan konten untuk root /
rute. Di mana pun Anda berada dalam hierarki file, halaman aktual untuk jalur tersebut selalu memiliki nama +page.svelte
. Dengan mengingat hal itu, mari buat halaman untuk /list
, /details
, /admin/user-settings
dan admin/paid-status
, dan juga tambahkan beberapa placeholder teks untuk setiap halaman.
Tata letak file Anda akan terlihat seperti ini:
Anda harus dapat menavigasi dengan mengubah jalur URL di bilah alamat browser.
layout
Kami menginginkan tautan navigasi di aplikasi kami, tetapi kami tentu saja tidak ingin menyalin markupnya di setiap halaman yang kami buat. Jadi, mari kita membuat +layout.svelte
file di root kami routes
folder, yang akan diperlakukan SvelteKit sebagai template global untuk semua halaman. Mari dan tambahkan beberapa konten ke dalamnya:
<nav> <ul> <li> <a href="/id/">Home</a> </li> <li> <a href="/id/list">To-Do list</a> </li> <li> <a href="/id/admin/paid-status">Account status</a> </li> <li> <a href="/id/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>
Beberapa navigasi dasar dengan beberapa gaya dasar. Yang sangat penting adalah <slot />
menandai. Ini adalah tidak slot yang Anda gunakan dengan komponen web dan shadow DOM, melainkan fitur Svelte yang menunjukkan tempat untuk meletakkan konten kita. Saat halaman dirender, konten halaman akan meluncur di tempat slot berada.
Dan sekarang kami memiliki beberapa navigasi! Kami tidak akan memenangkan kompetisi desain apa pun, tetapi kami tidak berusaha untuk itu.
Tata letak bersarang
Bagaimana jika kita ingin semua halaman admin mewarisi tata letak normal yang baru saja kita buat tetapi juga berbagi beberapa hal umum untuk semua halaman admin (namun hanya halaman admin)? Tidak masalah, kami menambahkan yang lain +layout.svelte
file di root kita admin
direktori, yang akan diwarisi oleh semua yang ada di bawahnya. Mari lakukan itu dan tambahkan konten ini:
<div>This is an admin page</div> <slot /> <style> div { padding: 15px; margin: 10px 0; background-color: red; color: white; }
</style>
Kami menambahkan spanduk merah yang menandakan ini adalah halaman admin dan kemudian, seperti sebelumnya, a <slot />
menunjukkan di mana kita ingin konten halaman kita pergi.
Tata letak root kami dari sebelum merender. Di dalam tata letak root adalah a <slot />
menandai. Konten tata letak bersarang masuk ke tata letak root <slot />
. Dan terakhir, tata letak bersarang mendefinisikannya sendiri <slot />
, tempat konten halaman dirender.
Jika Anda menavigasi ke halaman admin, Anda akan melihat spanduk merah baru:
Mendefinisikan data kita
Oke, mari kita render beberapa data aktual โ atau setidaknya, lihat bagaimana kita bisa merender beberapa data aktual. Ada seratus cara untuk membuat dan terhubung ke database. Posting ini adalah tentang SvelteKit, bukan mengelola DynamoDB, jadi kami akan "memuat" beberapa data statis sebagai gantinya. Namun, kami akan menggunakan semua mesin yang sama untuk membaca dan memperbaruinya seperti yang Anda gunakan untuk data nyata. Untuk aplikasi web nyata, tukar fungsi yang mengembalikan data statis dengan fungsi yang menghubungkan dan melakukan kueri ke database apa pun yang kebetulan Anda gunakan.
Mari kita buat modul sederhana di lib/data/todoData.ts
yang mengembalikan beberapa data statis bersama dengan penundaan buatan untuk mensimulasikan kueri nyata. Anda akan melihat ini lib
folder yang diimpor ke tempat lain melalui $lib
. Ini adalah fitur SvelteKit untuk folder tersebut, dan Anda bahkan bisa tambahkan alias Anda sendiri.
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);
}
Fungsi untuk mengembalikan larik datar dari item tugas kami, pencarian tag kami, dan fungsi untuk mengambil satu tugas (kami akan menggunakan yang terakhir di halaman Detail kami).
Memuat data kami
Bagaimana kami memasukkan data itu ke halaman Svelte kami? Ada beberapa cara, tapi untuk saat ini, mari kita buat +page.server.js
file di kami list
folder, dan letakkan konten ini di dalamnya:
import { getTodos, getTags } from "$lib/data/todoData"; export function load() { const todos = getTodos(); const tags = getTags(); return { todos, tags, };
}
Kami telah menentukan a load()
fungsi yang menarik data yang dibutuhkan untuk halaman. Perhatikan bahwa kita tidak await
-ing panggilan ke kami getTodos
dan getTags
fungsi asinkron. Melakukan hal itu akan membuat air terjun pemuatan data saat kami menunggu item tugas kami masuk sebelum memuat tag kami. Sebagai gantinya, kami mengembalikan janji mentah dari load
, dan SvelteKit melakukan pekerjaan yang diperlukan await
Mereka.
Jadi, bagaimana kita mengakses data ini dari komponen halaman kita? SvelteKit menyediakan a data
prop untuk komponen kita dengan data di dalamnya. Kami akan mengakses item tugas dan tag darinya menggunakan a penugasan reaktif.
Komponen halaman Daftar kami sekarang terlihat seperti ini.
<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>
Dan ini akan membuat item tugas kita!
Grup tata letak
Sebelum kita beralih ke halaman Detail dan memutasikan data, mari kita intip fitur SvelteKit yang sangat apik: kelompok tata letak. Kami telah melihat tata letak bersarang untuk semua halaman admin, tetapi bagaimana jika kami ingin berbagi tata letak antara halaman arbitrer pada tingkat sistem file yang sama? Khususnya, bagaimana jika kita ingin berbagi tata letak hanya antara halaman Daftar dan halaman Detail? Kami sudah memiliki tata letak global pada level itu. Sebagai gantinya, kita dapat membuat direktori baru, tetapi dengan nama yang ada di dalam tanda kurung, seperti ini:
Kami sekarang memiliki grup tata letak yang mencakup halaman Daftar dan Detail kami. Saya menamainya (todo-management)
tetapi Anda dapat menamainya sesuka Anda. Untuk lebih jelasnya, nama ini akan tidak memengaruhi URL laman di dalam grup tata letak. URL akan tetap sama; grup tata letak memungkinkan Anda untuk menambahkan tata letak bersama ke halaman tanpa semuanya terdiri dari keseluruhan direktori routes
.
We bisa tambah sebuah +layout.svelte
file dan beberapa konyol <div>
spanduk bertuliskan, "Hei, kami sedang mengatur to-dos". Tapi mari kita lakukan sesuatu yang lebih menarik. Tata letak dapat menentukan load()
berfungsi untuk menyediakan data untuk semua rute di bawahnya. Mari gunakan fungsi ini untuk memuat tag kita โ karena kita akan menggunakan tag kita di details
halaman โ selain list
halaman yang sudah kita miliki.
Pada kenyataannya, memaksa grup tata letak hanya untuk menyediakan satu bagian data hampir pasti tidak sepadan; lebih baik menduplikasi data itu di load()
fungsi untuk setiap halaman. Tapi untuk posting ini, itu akan memberikan alasan kita perlu melihat fitur baru SvelteKit!
Pertama, mari kita pergi ke kami list
halaman +page.server.js
file dan hapus tag darinya.
import { getTodos, getTags } from "$lib/data/todoData"; export function load() { const todos = getTodos(); return { todos, };
}
Halaman Daftar kami sekarang akan menghasilkan kesalahan karena tidak ada tags
obyek. Mari perbaiki ini dengan menambahkan a +layout.server.js
file di grup tata letak kami, lalu tentukan a load()
fungsi yang memuat tag kami.
import { getTags } from "$lib/data/todoData"; export function load() { const tags = getTags(); return { tags, };
}
Dan, begitu saja, halaman Daftar kita dirender lagi!
Kami memuat data dari beberapa lokasi
Mari kita jelaskan apa yang terjadi di sini:
- Kami mendefinisikan a
load()
fungsi untuk grup tata letak kami, yang kami masukkan+layout.server.js
. - Ini menyediakan data untuk semua halaman yang dilayani tata letak โ yang dalam hal ini berarti halaman Daftar dan Detail kami.
- Halaman Daftar kami juga mendefinisikan a
load()
fungsi yang terjadi di dalamnya+page.server.js
file. - SvelteKit melakukan pekerjaan kasar dengan mengambil hasil dari sumber data ini, menggabungkannya, dan menyediakan keduanya di
data
.
Halaman Detail kami
Kami akan menggunakan halaman Detail kami untuk mengedit item daftar tugas. Pertama, mari tambahkan kolom ke tabel di halaman Daftar kami yang tertaut ke halaman Detail dengan ID item daftar tugas di string kueri.
<td><a href="/id/details?id={t.id}">Edit</a></td>
Sekarang mari buat halaman Detail kita. Pertama, kita akan menambahkan loader untuk mengambil item agenda yang sedang kita edit. Membuat +page.server.js
in /details
, dengan konten ini:
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, };
}
Loader kami dilengkapi dengan a url
properti dari mana kita dapat menarik nilai string kueri. Hal ini memudahkan untuk mencari item agenda yang sedang kami edit. Mari kita buat agenda itu, bersama dengan fungsionalitas untuk mengeditnya.
SvelteKit memiliki kemampuan mutasi bawaan yang luar biasa, selama Anda menggunakan formulir. Ingat formulir? Inilah halaman Detail kami. Saya telah menghilangkan gaya untuk singkatnya.
<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>
Kami mengambil tag seperti sebelumnya dari pemuat grup tata letak kami dan item yang harus dilakukan dari pemuat halaman kami. Kami meraih yang sebenarnya tag
objek dari daftar ID tag tugas dan kemudian merender semuanya. Kami membuat formulir dengan masukan tersembunyi untuk ID dan masukan nyata untuk judul. Kami menampilkan tag dan kemudian memberikan tombol untuk mengirimkan formulir.
Jika Anda melihat use:enhance
, yang hanya memberi tahu SvelteKit untuk menggunakan peningkatan progresif dan Ajax untuk mengirimkan formulir kami. Anda mungkin akan selalu menggunakannya.
Bagaimana kita menyimpan suntingan kita?
Perhatikan action="?/editTodo"
atribut pada formulir itu sendiri? Ini memberi tahu kami di mana kami ingin mengirimkan data yang telah diedit. Untuk kasus kami, kami ingin menyerahkan ke editTodo
"tindakan."
Mari kita buat dengan menambahkan yang berikut ke +page.server.js
file yang sudah kami miliki untuk Detail (yang saat ini memiliki file load()
fungsi, untuk mengambil tugas kami):
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"); },
};
Bentuk tindakan memberi kita a request
objek, yang menyediakan akses ke kami formData
, yang memiliki a get
metode untuk berbagai bidang formulir kami. Kami menambahkan input tersembunyi untuk nilai ID sehingga kami dapat mengambilnya di sini untuk mencari item agenda yang sedang kami edit. Kami mensimulasikan penundaan, memanggil yang baru updateTodo()
metode, kemudian mengarahkan pengguna kembali ke /list
halaman. Itu updateTodo()
metode hanya memperbarui data statis kami; dalam kehidupan nyata Anda akan menjalankan semacam pembaruan di penyimpanan data apa pun yang Anda gunakan.
export async function updateTodo(id, newTitle) { const todo = todos.find(t => t.id == id); Object.assign(todo, { title: newTitle });
}
Mari kita coba. Kami akan pergi ke halaman Daftar terlebih dahulu:
Sekarang mari kita klik tombol Edit untuk salah satu item yang harus dilakukan untuk membuka halaman pengeditan /details
.
Kami akan menambahkan judul baru:
Sekarang, klik Simpan. Itu seharusnya membuat kita kembali ke kita /list
halaman, dengan judul agenda baru yang diterapkan.
Bagaimana judul baru muncul seperti itu? Itu otomatis. Setelah kami dialihkan ke /list
halaman, SvelteKit secara otomatis menjalankan ulang semua loader kami seperti yang akan dilakukannya. Ini adalah kemajuan utama dari kerangka kerja aplikasi generasi berikutnya, seperti SvelteKit, Remix, dan 13 berikutnya menyediakan. Alih-alih memberi Anda cara mudah untuk merender halaman lalu berharap yang terbaik untuk mengambil titik akhir apa pun yang mungkin Anda miliki untuk memperbarui data, mereka mengintegrasikan mutasi data bersamaan dengan pemuatan data, memungkinkan keduanya bekerja bersama-sama.
Beberapa hal yang mungkin membuat Anda bertanya-tanyaโฆ
Pembaruan mutasi ini sepertinya tidak terlalu mengesankan. Loader akan dijalankan kembali setiap kali Anda menavigasi. Bagaimana jika kita tidak menambahkan pengalihan dalam tindakan formulir kita, tetapi tetap berada di halaman saat ini? SvelteKit akan melakukan pembaruan dalam bentuk tindakan, seperti sebelumnya, tetapi akan masih jalankan kembali semua pemuat untuk halaman saat ini, termasuk pemuat di tata letak halaman.
Bisakah kita memiliki cara yang lebih bertarget untuk membatalkan data kita? Misalnya, tag kami tidak diedit, jadi dalam kehidupan nyata kami tidak ingin menanyakannya kembali. Ya, yang saya tunjukkan hanyalah perilaku formulir default di SvelteKit. Anda dapat mematikan perilaku default dengan memberikan panggilan balik ke use:enhance
. Kemudian SvelteKit menyediakan manual fungsi pembatalan.
Memuat data di setiap navigasi berpotensi mahal, dan tidak perlu. Bisakah saya menyimpan data ini seperti yang saya lakukan dengan alat seperti react-query
? Ya, hanya berbeda. SvelteKit memungkinkan Anda mengatur (dan kemudian menghargai) header kontrol-cache yang sudah disediakan web. Dan saya akan membahas mekanisme pembatalan cache di postingan selanjutnya.
Semua yang kami lakukan di sepanjang artikel ini menggunakan data statis dan mengubah nilai dalam memori. Jika Anda perlu mengembalikan semuanya dan memulai kembali, hentikan dan mulai ulang npm run dev
Proses simpul.
Membungkus
Kami baru saja menggores permukaan SvelteKit, tetapi mudah-mudahan Anda sudah cukup melihatnya untuk membuatnya bersemangat. Saya tidak ingat kapan terakhir kali saya menganggap pengembangan web sangat menyenangkan. Dengan hal-hal seperti bundling, perutean, SSR, dan penyebaran semuanya ditangani di luar kotak, saya menghabiskan lebih banyak waktu untuk membuat kode daripada mengonfigurasi.
Berikut adalah beberapa sumber lagi yang dapat Anda gunakan sebagai langkah selanjutnya untuk mempelajari SvelteKit:
- Konten Bertenaga SEO & Distribusi PR. Dapatkan Amplifikasi Hari Ini.
- Platoblockchain. Intelijen Metaverse Web3. Pengetahuan Diperkuat. Akses Di Sini.
- Sumber: https://css-tricks.com/getting-started-with-sveltekit/
- 1
- 10
- 100
- 11
- 7
- 9
- 98
- a
- Sanggup
- Tentang Kami
- tentang itu
- mengakses
- Akun
- Tindakan
- tindakan
- Adam
- menambahkan
- tambahan
- alamat
- admin
- maju
- mempengaruhi
- Semua
- Membiarkan
- di samping
- sudah
- selalu
- jumlah
- dan
- Lain
- menjawab
- siapapun
- aplikasi
- Aplikasi
- aplikasi
- terapan
- sekitar
- susunan
- artikel
- buatan
- ditugaskan
- secara otomatis
- secara otomatis
- tersedia
- menunggu
- kembali
- latar belakang
- spanduk
- bar
- dasar
- sebelum
- TERBAIK
- Lebih baik
- antara
- Bit
- Black
- Blog
- Posting blog
- Biru
- Kotak
- membawa
- Browser
- bug
- membangun
- dibangun di
- built-in
- tombol
- Cache
- panggilan
- Panggilan
- kemampuan
- kasus
- Pasti
- menantang
- mengubah
- jelas
- kode
- Pengkodean
- warna
- Kolom
- bagaimana
- Umum
- Kompetisi
- komponen
- komponen
- konferensi
- Terhubung
- Menghubungkan
- konsul
- Konten
- Mudah
- bisa
- Kelas
- penutup
- Meliputi
- membuat
- dibuat
- membuat
- terbaru
- Sekarang
- data
- Basis Data
- Default
- Mendefinisikan
- menunda
- keterlambatan
- penyebaran
- Mendesain
- rincian
- dev
- Pengembangan
- MELAKUKAN
- Display
- Tidak
- melakukan
- Dont
- setiap
- di tempat lain
- cukup
- Seluruh
- keseluruhan
- kesalahan
- dll
- Bahkan
- Setiap
- segala sesuatu
- contoh
- gembira
- Kegembiraan
- ada
- mahal
- ekspor
- layak
- Fitur
- beberapa
- Fields
- File
- File
- Akhirnya
- akhir
- Kebakaran
- Pertama
- Memperbaiki
- datar
- berikut
- selama-lamanya
- bentuk
- format
- bentuk
- ditemukan
- kerangka
- dari
- penuh
- kesenangan
- fungsi
- fungsi
- fungsi
- mendapatkan
- mendapatkan
- Memberikan
- Pemberian
- Aksi
- Go
- tujuan
- Pergi
- akan
- merebut
- Kelompok
- Grup
- terjadi
- Sulit
- header
- membantu
- di sini
- Tersembunyi
- hirarki
- tingkat tinggi
- memegang
- Mudah-mudahan
- Horisontal
- Seterpercayaapakah Olymp Trade? Kesimpulan
- HTML
- HTTPS
- SAYA AKAN
- imajinasi
- mengimpor
- pentingnya
- impresif
- in
- Termasuk
- mulanya
- memasukkan
- sebagai gantinya
- mengintegrasikan
- menarik
- Pengantar
- IT
- item
- Diri
- JavaScript
- kunci
- Terakhir
- Terbaru
- tata ruang
- pengetahuan
- Lets
- Tingkat
- Li
- Hidup
- cahaya
- Mungkin
- link
- Daftar
- hidup
- memuat
- pemuat
- pemuatan
- beban
- Panjang
- melihat
- TERLIHAT
- lookup
- keberuntungan
- mesin-mesin
- membuat
- MEMBUAT
- Membuat
- pelaksana
- panduan
- Margin
- hal
- cara
- Memori
- hanya
- penggabungan
- metode
- mungkin
- keberatan
- Modul
- lebih
- pindah
- bergerak
- beberapa
- nama
- Bernama
- nav
- Arahkan
- Navigasi
- perlu
- Perlu
- New
- berikutnya
- simpul
- normal
- jumlah
- obyek
- objek
- ONE
- urutan
- Lainnya
- jika tidak
- sendiri
- tertentu
- path
- Melakukan
- memilih
- bagian
- potongan-potongan
- placeholder
- plato
- Kecerdasan Data Plato
- Data Plato
- Titik
- Pos
- Posts
- berpotensi
- Mempersiapkan
- Masalah
- proses
- menghasilkan
- progresif
- proyek
- menjanjikan
- milik
- terlindung
- memberikan
- menyediakan
- Menarik
- menempatkan
- pertanyaan
- Mentah
- Baca
- nyata
- kehidupan nyata
- Kenyataan
- Merah
- redirect
- Bagaimanapun juga
- tinggal
- ingat
- menghapus
- render
- merender
- permintaan
- Sumber
- Hasil
- kembali
- kembali
- Pengembalian
- kembali
- Kaya
- akar
- Rute
- rute
- Run
- berjalan
- sama
- Save
- melihat
- melayani
- set
- bayangan
- Share
- berbagi
- harus
- Menunjukkan
- Sederhana
- hanya
- sejak
- tunggal
- Meluncur
- So
- beberapa
- sesuatu
- sumber
- menghabiskan
- awal
- mulai
- tinggal
- Tangga
- berhenti
- menyerahkan
- Mendukung
- Permukaan
- sistem
- tabel
- MENANDAI
- Mengambil
- pengambilan
- Berbicara
- Berduaan
- ditargetkan
- mengatakan
- Template
- terminal
- Grafik
- hal
- di seluruh
- waktu
- Judul
- untuk
- bersama
- terlalu
- alat
- Tour
- mengobati
- benar
- MENGHIDUPKAN
- Naskah
- ui
- bawah
- Memperbarui
- Pembaruan
- URL
- us
- menggunakan
- Pengguna
- nilai
- Nilai - Nilai
- berbagai
- melalui
- View
- menunggu
- ingin
- cara
- jaringan
- komponen web
- pengembangan web
- Apa
- yang
- putih
- akan
- menang
- tanpa
- hebat
- Kerja
- bekerja
- bernilai
- akan
- menulis
- Kamu
- Anda
- zephyrnet.dll