diff --git a/www/src/config.ts b/www/src/config.ts index 7e0418636c..8b64102ddf 100644 --- a/www/src/config.ts +++ b/www/src/config.ts @@ -31,6 +31,7 @@ export const KNOWN_LANGUAGES = { en: "English", es: "Español", fr: "Français", + id: "Bahasa Indonesia", ja: "日本語", pt: "Português", ru: "Русский", @@ -165,6 +166,37 @@ export const SIDEBAR: Sidebar = { { text: "Docker", link: "es/deployment/docker" }, ], }, + id: { + "Create T3 App": [ + { text: "Introduction", link: "id/introduction" }, + { text: "Why CT3A?", link: "id/why" }, + { text: "Installation", link: "id/installation" }, + { text: "Folder Structure", link: "id/folder-structure" }, + { text: "FAQ", link: "id/faq" }, + { text: "T3 Collection", link: "id/t3-collection" }, + { text: "Examples", link: "id/examples" }, + { text: "Other Recommendations", link: "id/other-recs" }, + ], + Usage: [ + { text: "First Steps", link: "id/usage/first-steps" }, + { text: "Next.js", link: "id/usage/next-js" }, + { text: "TypeScript", link: "id/usage/typescript" }, + { text: "tRPC", link: "id/usage/trpc" }, + { text: "Drizzle", link: "id/usage/drizzle" }, + { text: "Prisma", link: "id/usage/prisma" }, + { text: "NextAuth.js", link: "id/usage/next-auth" }, + { + text: "Environment Variables", + link: "id/usage/env-variables", + }, + { text: "Tailwind CSS", link: "id/usage/tailwind" }, + ], + Deployment: [ + { text: "Vercel", link: "id/deployment/vercel" }, + { text: "Netlify", link: "id/deployment/netlify" }, + { text: "Docker", link: "id/deployment/docker" }, + ], + }, ja: { "Create T3 App": [ { text: "イントロダクション", link: "ja/introduction" }, @@ -401,6 +433,11 @@ export const SIDEBAR_HEADER_MAP: Record< Usage: "كيفية الإستخدام؟", Deployment: "نَشر تطبيقك", }, + id: { + "Create T3 App": "Create T3 App", + Usage: "Pemakaian", + Deployment: "Deployment", + }, fr: { "Create T3 App": "Create T3 App", Usage: "Utilisation", diff --git a/www/src/pages/id/deployment/docker.md b/www/src/pages/id/deployment/docker.md new file mode 100644 index 0000000000..332ddffc34 --- /dev/null +++ b/www/src/pages/id/deployment/docker.md @@ -0,0 +1,216 @@ +--- +title: Docker +description: Deployment dengan Docker +layout: ../../../layouts/docs.astro +lang: id +--- + +Anda dapat membuat kontainer untuk tumpukan ini dan mendeploynya sebagai satu kontainer menggunakan Docker, atau sebagai bagian dari kelompok kontainer menggunakan docker-compose. Lihat [`ajcwebdev/ct3a-docker`](https://github.com/ajcwebdev/ct3a-docker) untuk repositori contoh berdasarkan dokumen ini. + +## Konfigurasi Proyek Docker + +Harap perhatikan bahwa Next.js memerlukan proses yang berbeda untuk waktu kompilasi (tersedia di frontend, diawali dengan `NEXT_PUBLIC`) dan variabel runtime, hanya server-side. Dalam demo ini, kami menggunakan dua variabel, perhatikan posisinya dalam `Dockerfile`, argumen baris perintah, dan `docker-compose.yml`: + +- `DATABASE_URL` (digunakan oleh server) +- `NEXT_PUBLIC_CLIENTVAR` (digunakan oleh client) + +### 1. Konfigurasi Next + +Di [`next.config.mjs`](https://github.com/t3-oss/create-t3-app/blob/main/cli/template/base/next.config.mjs) Anda, tambahkan konfigurasi output-option `standalone` untuk [mengurangi ukuran gambar secara otomatis dengan memanfaatkan jejak output](https://nextjs.org/docs/advanced-features/output-file-tracing): + +```diff +export default defineNextConfig({ + reactStrictMode: true, + swcMinify: true, ++ output: "standalone", +}); +``` + +### 2. Buat file .dockerignore + +
+ + Klik di sini dan sertakan konten dalam .dockerignore: + +
+ +``` +.env +Dockerfile +.dockerignore +node_modules +npm-debug.log +README.md +.next +.git +``` + +
+ +
+ +### 3. Buat Dockerfile + +> Karena kita tidak menarik variabel lingkungan server ke dalam kontainer kami, validasi skema lingkungan akan gagal. Untuk mencegah ini, kita harus menambahkan flag `SKIP_ENV_VALIDATION=1` ke perintah build sehingga skema env tidak divalidasi saat waktu kompilasi. + +
+ + Klik di sini dan sertakan konten dalam Dockerfile: + +
+ +```docker +##### DEPENDENCIES + +FROM --platform=linux/amd64 node:16-alpine3.17 AS deps +RUN apk add --no-cache libc6-compat openssl1.1-compat +WORKDIR /app + +# Install Prisma Client - remove if not using Prisma + +COPY prisma ./ + +# Install dependencies based on the preferred package manager + +COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml\* ./ + +RUN \ + if [ -f yarn.lock ]; then yarn --frozen-lockfile; \ + elif [ -f package-lock.json ]; then npm ci; \ + elif [ -f pnpm-lock.yaml ]; then yarn global add pnpm && pnpm i; \ + else echo "Lockfile not found." && exit 1; \ + fi + +##### BUILDER + +FROM --platform=linux/amd64 node:16-alpine3.17 AS builder +ARG DATABASE_URL +ARG NEXT_PUBLIC_CLIENTVAR +WORKDIR /app +COPY --from=deps /app/node_modules ./node_modules +COPY . . + +# ENV NEXT_TELEMETRY_DISABLED 1 + +RUN \ + if [ -f yarn.lock ]; then SKIP_ENV_VALIDATION=1 yarn build; \ + elif [ -f package-lock.json ]; then SKIP_ENV_VALIDATION=1 npm run build; \ + elif [ -f pnpm-lock.yaml ]; then yarn global add pnpm && SKIP_ENV_VALIDATION=1 pnpm run build; \ + else echo "Lockfile not found." && exit 1; \ + fi + +##### RUNNER + +FROM --platform=linux/amd64 node:16-alpine3.17 AS runner +WORKDIR /app + +ENV NODE_ENV production + +# ENV NEXT_TELEMETRY_DISABLED 1 + +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs + +COPY --from=builder /app/next.config.mjs ./ +COPY --from=builder /app/public ./public +COPY --from=builder /app/package.json ./package.json + +COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ +COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static + +USER nextjs +EXPOSE 3000 +ENV PORT 3000 + +CMD ["node", "server.js"] + +``` + +> **_Catatan_** +> +> - _Emulasi `--platform=linux/amd64` mungkin tidak perlu setelah beralih ke Node 18._ +> - _Lihat [`node:alpine`](https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine) untuk memahami mengapa `libc6-compat` mungkin diperlukan._ +> - _Menggunakan gambar berbasis Alpine 3.17 [dapat menyebabkan masalah dengan Prisma](https://github.com/t3-oss/create-t3-app/issues/975). Menetapkan `engineType = "binary"` memecahkan masalah di Alpine 3.17, [tetapi memiliki biaya kinerja terkait](https://www.prisma.io/docs/concepts/components/prisma-engines/query-engine#the-query-engine-at-runtime)._ +> - _Next.js mengumpulkan [data telemetri anonim tentang penggunaan umum](https://nextjs.org/telemetry). Hapus komentar pada contoh pertama `ENV NEXT_TELEMETRY_DISABLED 1` untuk menonaktifkan telemetri selama waktu kompilasi. Hapus komentar pada contoh kedua untuk menonaktifkan telemetri selama waktu runtime._ + +
+
+ +## Bangun dan Jalankan Gambar Secara Lokal + +Bangun dan jalankan gambar ini secara lokal dengan perintah berikut: + +```bash +docker build -t ct3a-docker --build-arg NEXT_PUBLIC_CLIENTVAR=clientvar . +docker run -p 3000:3000 -e DATABASE_URL="database_url_goes_here" ct3a-docker + + +``` + +Buka [localhost:3000](http://localhost:3000/) untuk melihat aplikasi yang berjalan. + +## Docker Compose + +Anda juga dapat menggunakan Docker Compose untuk membangun gambar dan menjalankan kontainer. + +
+ + Ikuti langkah 1-4 di atas, klik di sini, dan sertakan konten dalam docker-compose.yml: + +
+ +```yaml +version: "3.9" +services: + app: + platform: "linux/amd64" + build: + context: . + dockerfile: Dockerfile + args: + NEXT_PUBLIC_CLIENTVAR: "clientvar" + working_dir: /app + ports: + - "3000:3000" + image: t3-app + environment: + - DATABASE_URL=database_url_goes_here +``` + +Jalankan ini menggunakan perintah `docker compose up`: + +```bash +docker compose up +``` + +Buka [localhost:3000](http://localhost:3000/) untuk melihat aplikasi yang berjalan. + +
+
+ +## Deploy ke Railway + +Anda dapat menggunakan PaaS seperti [Railway](https://railway.app) yang otomatis [menggunakan Dockerfile untuk mendeploy aplikasi](https://docs.railway.app/deploy/dockerfiles) untuk mendeploy aplikasi Anda. Jika Anda telah menginstal [Railway CLI](https://docs.railway.app/develop/cli#install), Anda dapat mendeploy aplikasi Anda dengan perintah berikut: + +```bash +railway login +railway init +railway link +railway up +railway open +``` + +Buka "Variables" dan sertakan `DATABASE_URL` Anda. Kemudian buka "Settings" dan pilih "Generate Domain." Untuk melihat contoh yang berjalan di Railway, kunjungi [ct3a-docker.up.railway.app](https://ct3a-docker.up.railway.app/). + +## Sumber Daya Berguna + +| Sumber Daya | Tautan | +| ------------------------------------------- | ---------------------------------------------------------------------- | +| Referensi Dockerfile | | +| Referensi Compose file versi 3 | | +| Referensi CLI Docker | | +| Referensi CLI Docker Compose | | +| Next.js Deployment dengan Docker Image | | +| Next.js di Docker | | +| Contoh Next.js dengan Docker | | +| Membuat Gambar Docker dari aplikasi Next.js | | diff --git a/www/src/pages/id/deployment/index.astro b/www/src/pages/id/deployment/index.astro new file mode 100644 index 0000000000..40b21cb888 --- /dev/null +++ b/www/src/pages/id/deployment/index.astro @@ -0,0 +1,24 @@ +--- +import IndexPage from "../../../components/docs/indexPage.astro"; +import { SIDEBAR, type Frontmatter } from "../../../config"; +import { getLanguageFromURL } from "../../../languages"; +import Layout from "../../../layouts/docs.astro"; + +const frontmatter: Frontmatter = { + title: "Deployment", + layout: "docs", + description: "Pelajari cara men-deploy aplikasi T3 Anda dalam produksi.", +}; + +const lang = getLanguageFromURL(Astro.url.pathname); +const sidebarEntries = SIDEBAR[lang]["Deployment"]!; +const files = await Astro.glob("./*.{md,mdx,astro}"); +--- + + + + diff --git a/www/src/pages/id/deployment/netlify.mdx b/www/src/pages/id/deployment/netlify.mdx new file mode 100644 index 0000000000..f39191491b --- /dev/null +++ b/www/src/pages/id/deployment/netlify.mdx @@ -0,0 +1,92 @@ +--- +title: Netlify +description: Penyedia Deploy ke Netlify +layout: ../../../layouts/docs.astro +lang: id +isMdx: true +--- + +import Callout from "../../../components/docs/callout.tsx"; + +Netlify adalah penyedia deploy alternatif yang sejenis dengan Vercel. Lihat [`ajcwebdev/ct3a-netlify`](https://github.com/ajcwebdev/ct3a-netlify) untuk repositori contoh berdasarkan dokumen ini. + +## Mengapa Menggunakan Netlify + +Pandangan umum mengatakan bahwa Vercel memiliki dukungan yang lebih baik untuk Next.js karena Vercel mengembangkan Next.js. Mereka memiliki kepentingan dalam memastikan platform ini disesuaikan untuk kinerja optimal dan pengembangan yang baik dengan Next.js. Untuk sebagian besar kasus penggunaan, hal ini akan benar dan tidak akan masuk akal untuk menyimpang dari jalur standar. + +Ada juga pendapat umum bahwa banyak fitur Next.js hanya didukung di Vercel. Meskipun benar bahwa fitur-fitur Next.js baru akan diuji dan didukung di Vercel pada saat rilis secara default, juga benar bahwa penyedia lain seperti Netlify akan [cepat mengimplementasikan dan merilis dukungan](https://www.netlify.com/blog/deploy-nextjs-13/) untuk [fitur Next.js yang stabil](https://docs.netlify.com/integrations/frameworks/next-js/overview/). + +Ada pro dan kontra relatif untuk semua penyedia deploy karena tidak ada satu host yang dapat memiliki dukungan terbaik untuk semua kasus penggunaan. Misalnya, Netlify membangun [runtime Next.js kustom mereka sendiri](https://github.com/netlify/next-runtime) untuk Fungsi Edge Netlify (yang berjalan di Deno Deploy) dan [mempertahankan middleware unik untuk mengakses dan mengubah respons HTTP](https://github.com/netlify/next-runtime#nextjs-middleware-on-netlify). + + + Untuk melacak status fitur-fitur Next 13 yang tidak stabil, lihat [Menggunakan Direktori `app` Next 13 + di Netlify](https://github.com/netlify/next-runtime/discussions/1724). + + +## Konfigurasi Proyek + +Ada banyak cara untuk mengonfigurasi instruksi pembangunan Anda, termasuk langsung melalui Netlify CLI atau dashboard Netlify. Meskipun tidak diperlukan, disarankan untuk membuat dan menyertakan file [`netlify.toml`](https://docs.netlify.com/configure-builds/file-based-configuration/) ini. Ini memastikan versi yang diforkan dan diklon dari proyek akan lebih mudah untuk dideploy secara reproduksi. + +```toml +[build] + command = "next build" + publish = ".next" +``` + +## Menggunakan Dashboard Netlify + +1. Unggah kode Anda ke repositori GitHub dan daftar untuk [Netlify](https://app.netlify.com/signup). Setelah Anda membuat akun, klik **Tambahkan situs baru** dan kemudian **Impor proyek yang ada**. + +![Proyek baru di Netlify](/images/netlify-01-proyek-baru.webp) + +2. Sambungkan penyedia Git Anda. + +![Impor repositori](/images/netlify-02-terhubung-ke-penyedia-git.webp) + +3. Pilih repositori proyek Anda. + +![Pilih repositori proyek Anda](/images/netlify-03-pilih-repositori-dari-github.webp) + +4. Netlify akan mendeteksi jika Anda memiliki file `netlify.toml` dan secara otomatis mengonfigurasi perintah pembangunan dan direktori penerbitan Anda. + +![Pengaturan build Next.js](/images/netlify-04-konfigurasi-pengaturan-build.webp) + +5. Klik **Tampilkan lanjutan** dan kemudian **Variabel baru** untuk menambahkan variabel lingkungan Anda. + +![Tambahkan variabel lingkungan](/images/netlify-05-variabel-lingkungan.webp) + +6. Klik **Deploy situs**, tunggu hingga proses pembangunan selesai, dan lihat situs baru Anda. + +## Menggunakan Netlify CLI + +Untuk melakukan deploy dari baris perintah, Anda harus terlebih dahulu mengunggah proyek Anda ke repo GitHub dan [menginstal Netlify CLI](https://docs.netlify.com/cli/get-started/). Anda dapat menginstal `netlify-cli` sebagai dependensi proyek atau menginstalnya secara global di mesin Anda dengan perintah berikut: + +```bash +npm i -g netlify-cli +``` + +Untuk menguji proyek Anda secara lokal, jalankan perintah [`ntl dev`](https://docs.netlify.com/cli/get-started/#run-a-local-development-environment) dan buka [`localhost:8888`](http://localhost:8888/) untuk melihat aplikasi Netlify Anda yang berjalan secara lokal: + +```bash +ntl dev +``` + +Jalankan perintah [`ntl init`](https://docs.netlify.com/cli/get-started/#continuous-deployment) untuk mengonfigurasi proyek Anda: + +```bash +ntl init +``` + +Impor variabel lingkungan proyek Anda dari file `.env` Anda dengan perintah [`ntl env:import`](https://cli.netlify.com/commands/env#envimport): + +```bash +ntl env:import .env +``` + +Deploy proyek Anda dengan perintah [`ntl deploy`](https://docs.netlify.com/cli/get-started/#manual-deploys). Anda perlu melewati flag `--build` untuk menjalankan perintah build sebelum deploy dan flag `--prod` untuk melakukan deploy ke URL utama situs Anda: + +```bash +ntl deploy --prod --build +``` + +Untuk melihat contoh yang berjalan di Netlify, kunjungi [ct3a.netlify.app](https://ct3a.netlify.app/). \ No newline at end of file diff --git a/www/src/pages/id/deployment/vercel.md b/www/src/pages/id/deployment/vercel.md new file mode 100644 index 0000000000..d9a175bb4a --- /dev/null +++ b/www/src/pages/id/deployment/vercel.md @@ -0,0 +1,63 @@ +--- +title: Vercel +description: Deploy ke Vercel +layout: ../../../layouts/docs.astro +lang: id +--- + +Kami merekomendasikan untuk melakukan deploy aplikasi Anda ke [Vercel](https://vercel.com/?utm_source=t3-oss&utm_campaign=oss). Ini sangat mudah untuk melakukan deploy aplikasi Next.js. + +## Konfigurasi Proyek + +Vercel kemungkinan akan mengonfigurasi perintah pembangunan Anda dan direktori penerbitan secara otomatis. Namun, Anda juga dapat menentukan informasi ini bersama dengan konfigurasi lainnya dengan membuat file bernama [`vercel.json`](https://vercel.com/docs/project-configuration) dan menyertakan perintah-perintah berikut. **Ini tidak diperlukan untuk sebagian besar proyek.** + +```json +{ + "buildCommand": "npm run build", + "outputDirectory": "dist", + "devCommand": "npm run dev", + "installCommand": "npm install" +} +``` + +## Menggunakan Dashboard Vercel + +1. Setelah mengunggah kode Anda ke repositori GitHub, daftar ke [Vercel](https://vercel.com/?utm_source=t3-oss&utm_campaign=oss) dengan GitHub dan klik **Tambahkan Proyek Baru**. + +![Proyek baru di Vercel](/images/vercel-proyek-baru.webp) + +2. Impor repositori GitHub dengan proyek Anda. + +![Impor repositori](/images/vercel-impor-proyek.webp) + +3. Tambahkan variabel lingkungan Anda. + +![Tambahkan variabel lingkungan](/images/vercel-variabel-lingkungan.webp) + +4. Klik **Deploy**. Sekarang, setiap kali Anda melakukan perubahan pada repositori Anda, Vercel akan secara otomatis melakukan redeploy aplikasi Anda! + +## Menggunakan Vercel CLI + +Untuk melakukan deploy dari baris perintah, Anda harus terlebih dahulu [menginstal Vercel CLI secara global](https://vercel.com/docs/cli#installing-vercel-cli). + +```bash +npm i -g vercel +``` + +Jalankan perintah [`vercel`](https://vercel.com/docs/cli/deploying-from-cli) untuk melakukan deploy proyek Anda. + +```bash +vercel +``` + +Sertakan `--env DATABASE_URL=URL_KONEKSI_DATABASE_ANDA_DI_SINI` untuk variabel lingkungan seperti string koneksi database. Gunakan `--yes` jika Anda ingin melewati pertanyaan-pertanyaan deployment dan memberikan jawaban default untuk setiap pertanyaan. + +```bash +vercel --env DATABASE_URL=URL_KONEKSI_DATABASE_ANDA_DI_SINI --yes +``` + +Setelah deployment pertama, perintah ini akan melakukan deploy ke cabang pratinjau. Anda perlu menyertakan `--prod` untuk mendorong perubahan langsung ke situs langsung untuk deployment di masa mendatang. + +```bash +vercel --prod +``` diff --git a/www/src/pages/id/examples.mdx b/www/src/pages/id/examples.mdx new file mode 100644 index 0000000000..eb6f37fa16 --- /dev/null +++ b/www/src/pages/id/examples.mdx @@ -0,0 +1,22 @@ +--- +title: Contoh +description: Contoh aplikasi langsung yang berbeda +layout: ../../layouts/docs.astro +lang: id +isMdx: true +--- + +import Callout from "../../components/docs/callout.tsx"; +import Form from "../../components/docs/exampleOptionForm.astro"; + +Anda dapat mencoba berbagai kombinasi teknologi yang ditawarkan oleh create-t3-app. + + + Anda tidak dapat memilih `prisma` dan `drizzle` secara bersamaan. + + +
+ + + Beberapa fitur mungkin tidak berfungsi kecuali Anda membuat file env + diff --git a/www/src/pages/id/faq.mdx b/www/src/pages/id/faq.mdx new file mode 100644 index 0000000000..28be2bbf19 --- /dev/null +++ b/www/src/pages/id/faq.mdx @@ -0,0 +1,76 @@ +--- +title: Pertanyaan Umum +description: Pertanyaan yang Sering Diajukan tentang Create T3 App +layout: ../../layouts/docs.astro +lang: id +isMdx: true +--- + +import Callout from "../../components/docs/callout.tsx"; + +Berikut adalah beberapa pertanyaan yang sering diajukan tentang Create T3 App. + +## Apa selanjutnya? Bagaimana cara membuat aplikasi dengan ini? + +Kami mencoba menjaga proyek ini sesederhana mungkin, sehingga Anda dapat memulainya hanya dengan kerangka kerja yang kami sediakan, dan menambahkan hal-hal tambahan nanti ketika dibutuhkan. + +Jika Anda tidak familiar dengan teknologi yang digunakan dalam proyek ini, silakan merujuk ke dokumen-dokumen yang sesuai. Jika Anda masih bingung, silakan bergabung dengan [Discord kami](https://t3.gg/discord) dan minta bantuan. + +- [Next.js](https://nextjs.org/) +- [NextAuth.js](https://next-auth.js.org) +- [Prisma](https://prisma.io) +- [Tailwind CSS](https://tailwindcss.com) +- [tRPC](https://trpc.io) +- [Drizzle](https://orm.drizzle.team/docs/overview) + +## Bagaimana cara menjaga aplikasi saya tetap terbaru? + +Create T3 App adalah alat pemancangan, bukan sebuah kerangka kerja. Ini berarti bahwa setelah Anda menginisialisasi sebuah aplikasi, itu menjadi milik Anda. Tidak ada alat baris perintah pascapasang seperti yang ada untuk membantu Anda tetap terbaru. Jika Anda ingin melacak perbaikan yang kami buat pada template, Anda dapat [mengaktifkan pemberitahuan untuk rilis](https://docs.github.com/id/account-and-profile/managing-subscriptions-and-notifications-on-github/setting-up-notifications/configuring-your-watch-settings-for-an-individual-repository) di repositori kami. Meskipun demikian, tidak perlu mengimplementasikan setiap perubahan yang kami buat pada template ke dalam aplikasi Anda. + +## Apa sumber daya pembelajaran yang saat ini tersedia? + +Meskipun sumber daya yang terdaftar di bawah ini merupakan yang terbaik yang ada untuk T3 Stack, komunitas (dan [Theo](https://youtu.be/rzwaaWH0ksk?t=1436)) merekomendasikan untuk langsung memulai menggunakan stack ini dan belajar seiring berjalannya waktu dengan membangun dengan stack ini. + +Jika Anda mempertimbangkan Create T3 App, kemungkinan Anda sudah menggunakan beberapa bagian dari stack ini. Jadi, mengapa tidak langsung melompat dan belajar bagian-bagian lainnya saat Anda membangun sesuatu? + +Sekarang, kami menyadari bahwa jalur ini tidak cocok untuk semua orang. Jadi, jika Anda merasa sudah mencoba rekomendasi ini dan masih ingin beberapa sumber daya, atau Anda hanya tidak percaya diri melakukannya sendiri dan/atau merasa overwhelmed oleh stack ini, cek tutorial-tutorial menarik ini tentang Create T3 App: + +### Artikel + +Beberapa di antaranya mungkin sudah usang. + +- [Sorotan pertama tentang Create T3 App](https://dev.to/ajcwebdev/a-first-look-at-create-t3-app-1i8f) +- [Migrasi Aplikasi T3 Anda ke Turborepo](https://www.jumr.dev/blog/t3-turbo) +- [Integrasi Stripe ke Aplikasi T3 Anda](https://blog.nickramkissoon.com/posts/integrate-stripe-t3) + +### Video + +- [Tutorial T3 Stack - DARI 0 KE PROD DENGAN $0 (Next.js, tRPC, TypeScript, Tailwind, Prisma & Lainnya)](https://www.youtube.com/watch?v=YkOSUVzOAA4) **(direkomendasikan)** +- [Jack Herrington - Membangun Aplikasi Catatan dengan T3 Stack](https://www.youtube.com/watch?v=J1gzN1SAhyM) +- [Membangun Klon Twitter dengan T3 Stack - tRPC, Next.js, Prisma, Tailwind & Zod](https://www.youtube.com/watch?v=nzJsYJPCc80) +- [Membangun Blog dengan T3 Stack - tRPC, TypeScript, Next.js, Prisma & Zod](https://www.youtube.com/watch?v=syEWlxVFUrY) +- [Membangun Aplikasi Chat Langsung dengan T3 Stack - TypeScript, Tailwind, tRPC](https://www.youtube.com/watch?v=dXRRY37MPuk) +- [T3 Stack - Bagaimana Kami Membuatnya](https://www.youtube.com/watch?v=H-FXwnEjSsI) +- [Gambaran Umum tentang Create T3 App (Next, Typescript, Tailwind, tRPC, Next-Auth)](https://www.youtube.com/watch?v=VJH8dsPtbeU) + +## Mengapa ada file `.js` dalam proyek? + +Sejalan dengan [T3-Aksioma #3](/id/introduction#typesafety-isnt-optional), kami menganggap keselamatan jenis sebagai warga negara kelas pertama. Sayangnya, tidak semua kerangka kerja dan plugin mendukung TypeScript, yang berarti beberapa file konfigurasi harus menjadi file `.js`. + +Kami mencoba menekankan bahwa file-file ini adalah JavaScript dengan alasan tertentu, dengan secara eksplisit mendeklarasikan jenis masing-masing file (`cjs` atau `mjs`) tergantung pada apa yang didukung oleh perpustakaan yang digunakan. Selain itu, semua file `js` dalam proyek ini masih diperiksa jenisnya menggunakan opsi checkJs dalam kompiler (tsconfig). + +## Saya kesulitan menambahkan i18n ke aplikasi saya. Apakah ada referensi yang bisa saya gunakan? + +Kami telah memutuskan untuk tidak menyertakan i18n secara default dalam `create-t3-app` karena ini adalah topik yang sangat subjektif dan ada banyak cara untuk mengimplementasikannya. + +Namun, jika Anda kesulitan mengimplementasikannya dan ingin melihat proyek referensi, kami memiliki [repo referensi](https://github.com/juliusmarminge/t3-i18n) yang menunjukkan bagaimana Anda dapat menambahkan i18n ke aplikasi T3 menggunakan [next-i18next](https://github.com/i18next/next-i18next). + +## Mengapa kita menggunakan `/pages` dan tidak `/app` dari Next.js 13? + +Sejalan dengan [T3-Aksioma #2](/id/introduction#bleed-responsibly), kami menyukai hal-hal yang paling mutakhir tetapi juga menghargai stabilitas, seluruh router Anda sulit dipindahkan, [bukan tempat yang baik untuk eksperimen](https://youtu.be/mnwUbtieOuI?t=1662). Meskipun `/app` adalah [sekilas ke masa depan](https://youtu.be/rnsC-12PVlM?t=818), itu belum siap untuk produksi; API-nya masih dalam beta dan diharapkan akan mengalami perubahan yang merusak. + + + Untuk daftar fitur yang didukung, direncanakan, dan sedang dikerjakan di direktori `/app`, + kunjungi [dokumentasi beta Next.js + (https://beta.nextjs.org/docs/app-directory-roadmap#supported-and-planned-features). + diff --git a/www/src/pages/id/folder-structure.mdx b/www/src/pages/id/folder-structure.mdx new file mode 100644 index 0000000000..214c688edc --- /dev/null +++ b/www/src/pages/id/folder-structure.mdx @@ -0,0 +1,212 @@ +--- +title: Struktur Folder +description: Struktur folder aplikasi T3 yang baru dibuat +layout: ../../layouts/docs.astro +lang: id +isMdx: true +--- + +import Diagram from "../../components/docs/folderStructureDiagram.astro"; +import Form from "../../components/docs/folderStructureForm.astro"; + +Silakan pilih paket Anda untuk melihat struktur folder dari aplikasi yang baru saja dibuat dengan pilihan tersebut. Lebih lanjut, Anda akan menemukan deskripsi dari setiap entri. + + + + + +
+ +### `prisma` + +Folder `prisma` berisi file `schema.prisma` yang digunakan untuk mengkonfigurasi koneksi database dan skema database. Ini juga merupakan lokasi untuk menyimpan file migrasi dan/atau skrip seed, jika digunakan. Lihat [Penggunaan Prisma](/id/usage/prisma) untuk informasi lebih lanjut. + +
+
+ +### `public` + +Folder `public` berisi aset statis yang disajikan oleh server web. File `favicon.ico` adalah contoh dari aset statis. + +
+
+ +### `src/env` + +Digunakan untuk validasi variabel lingkungan dan definisi tipe - lihat [Variabel Lingkungan](usage/env-variables). + +
+
+ +### `src/pages` + +Folder `pages` berisi semua halaman aplikasi Next.js. File `index.tsx` di direktori root `/pages` adalah halaman beranda aplikasi. File `_app.tsx` digunakan untuk membungkus aplikasi dengan penyedia. Lihat [Dokumentasi Next.js](https://nextjs.org/docs/basic-features/pages) untuk informasi lebih lanjut. + +
+
+ +#### `src/pages/api` + +Folder `api` berisi semua rute API aplikasi Next.js. Lihat [Dokumentasi Rute API Next.js](https://nextjs.org/docs/api-routes/introduction) untuk informasi tentang rute API. + +
+
+ +#### `src/pages/api/auth/[...nextauth].ts` + +File `[...nextauth].ts` adalah rute slug otentikasi NextAuth.js. Digunakan untuk menangani permintaan otentikasi. Lihat [Penggunaan NextAuth.js](usage/next-auth) untuk informasi lebih lanjut tentang NextAuth.js, dan [Dokumentasi Rute Dinamis Next.js](https://nextjs.org/docs/routing/dynamic-routes) untuk informasi tentang rute tangkap semua/slug. + +
+
+ +#### `src/pages/api/trpc/[trpc].ts` + +File `[trpc].ts` adalah titik masuk API tRPC. Digunakan untuk menangani permintaan tRPC. Lihat [Penggunaan tRPC](usage/trpc#-pagesapitrpctrpcts) untuk informasi lebih lanjut tentang file ini, dan [Dokumentasi Rute Dinamis Next.js](https://nextjs.org/docs/routing/dynamic-routes) untuk informasi tentang rute tangkap semua/slug. + +
+
+ +### `src/server` + +Folder `server` digunakan untuk memisahkan kode sisi server dengan kode sisi klien. + +
+
+ +#### `src/server/auth.ts` + +Titik masuk utama untuk logika otentikasi sisi server. Di sini, kami mengatur [opsi konfigurasi NextAuth.js](usage/next-auth), melakukan [augmentasi modul](usage/next-auth#inclusion-of-userid-on-the-session), serta menyediakan beberapa utilitas DX untuk otentikasi seperti mengambil sesi pengguna di sisi server. Lihat [Penggunaan NextAuth.js](usage/next-auth#usage-with-trpc) untuk informasi lebih lanjut. + +
+
+ +#### `src/server/db.ts` + +File `db.ts` digunakan untuk menginisialisasi klien Prisma pada lingkup global. Lihat [Penggunaan Prisma](usage/prisma#prisma-client) dan [praktik terbaik untuk menggunakan Prisma dengan Next.js](https://www.prisma.io/docs/guides/database/troubleshooting-orm/help-articles/nextjs-prisma-client-dev-practices) untuk informasi lebih lanjut. + +
+
+ +### `src/server/api` + +Folder `api` berisi kode sisi server tRPC. + +
+
+ +#### `src/server/api/routers` + +Folder `routers` berisi semua sub-router tRPC Anda. + +
+
+ +#### `src/server/api/routers/example.ts` + +File `example.ts` adalah contoh router tRPC yang menggunakan helper `publicProcedure` untuk menunjukkan bagaimana membuat rute tRPC publik. + +Tergantung pada paket yang Anda pilih, router ini mungkin berisi lebih atau kurang rute untuk mendemonstrasikan penggunaan sesuai kebutuhan Anda. + +
+
+ +#### `src/server/api/trpc.ts` + +File `trpc.ts` adalah file konfigurasi utama untuk back-end tRPC Anda. Di sini kami: + +1. Mendefinisikan konteks yang digunakan dalam permintaan tRPC. Lihat [Penggunaan tRPC](usage/trpc#-serverapitrpctrpcts) untuk informasi lebih lanjut. +2. Eksport helper procedure. Lihat [Penggunaan tRPC](usage/trpc#-serverapitrpctrpcts) untuk informasi lebih lanjut. + +
+ +
+ +#### `src/server/api/root.ts` + +File `root.ts` digunakan untuk menggabungkan router tRPC dan mengekspornya sebagai satu router, serta definisi tipe router. Lihat [Penggunaan tRPC](usage/trpc#-serverapirootts) untuk informasi lebih lanjut. + +
+
+ +### `src/styles` + +Folder `styles` berisi gaya global aplikasi. + +
+
+ +### `src/utils` + +Folder `utils` digunakan untuk menyimpan fungsi utilitas yang sering digunakan. + +
+
+ +#### `src/utils/api.ts` + +File `api.ts` adalah titik masuk frontend ke tRPC. Lihat [Penggunaan tRPC](usage/trpc#-utilsapits) untuk informasi lebih lanjut. + +
+
+ +### `.env` + +File `.env` digunakan untuk menyimpan variabel lingkungan. Lihat [Variabel Lingkungan](usage/env-variables) untuk informasi lebih lanjut. File ini **tidak boleh** dicommit ke sejarah git. + +
+
+ +### `.env.example` + +File `.env.example` menampilkan contoh variabel lingkungan berdasarkan pustaka yang dipilih. File ini harus dicommit ke sejarah git. + +
+
+ +### `.eslintrc.cjs` + +File `.eslintrc.cjs` digunakan untuk mengkonfigurasi ESLint. Lihat [Dokumentasi ESLint](https://eslint.org/docs/latest/user-guide/configuring/configuration-files) untuk informasi lebih lanjut. + +
+
+ +### `next-env.d.ts` + +File `next-env.d.ts` memastikan tipe Next.js diakui oleh kompiler TypeScript. **Anda tidak boleh menghapusnya atau mengeditnya karena dapat berubah kapan saja.** Lihat [Dokumentasi Next.js](https://nextjs.org/docs/basic-features/typescript#existing-projects) untuk informasi lebih lanjut. + +
+
+ +### `next.config.mjs` + +File `next.config.mjs` digunakan untuk mengkonfigurasi Next.js. Lihat [Dokumentasi Next.js](https://nextjs.org/docs/api-reference/next.config.js/introduction) untuk informasi lebih lanjut. Catatan: Ekstensi .mjs digunakan untuk mengizinkan impor ESM. + +
+
+ +### `postcss.config.cjs` + +File `postcss.config.cjs` digunakan untuk penggunaan Tailwind PostCSS. Lihat [Dokumentasi Tailwind PostCSS](https://tailwindcss.com/docs/installation/using-postcss) untuk informasi lebih lanjut. + +
+
+ +### `prettier.config.mjs` + +File `prettier.config.mjs` digunakan untuk mengkonfigurasi Prettier agar mencakup prettier-plugin-tailwindcss untuk mengatur kelas-kelas Tailwind CSS. Lihat [posting blog Tailwind CSS](https://tailwindcss.com/blog/automatic-class-sorting-with-prettier) untuk informasi lebih lanjut. + +
+
+ +### `tsconfig.json` + +File `tsconfig.json` digunakan untuk mengkonfigurasi TypeScript. Beberapa non-default, seperti `strict mode`, telah diaktifkan untuk memastikan penggunaan terbaik TypeScript untuk Create T3 App dan pustakanya. Lihat [Dokumentasi TypeScript](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html) atau [Penggunaan TypeScript](usage/typescript) untuk informasi lebih lanjut. + +
+
+ +### `drizzle.config.ts` + +File `drizzle.config.ts` digunakan untuk mengkonfigurasi drizzle kit. Lihat [dokumentasi](https://orm.drizzle.team/kit-docs/config-reference) untuk informasi lebih lanjut. + +
diff --git a/www/src/pages/id/installation.mdx b/www/src/pages/id/installation.mdx new file mode 100644 index 0000000000..169fa3585e --- /dev/null +++ b/www/src/pages/id/installation.mdx @@ -0,0 +1,72 @@ +--- +title: Instalasi +description: Instruksi instalasi untuk Create T3 App +layout: ../../layouts/docs.astro +lang: id +isMdx: true +--- + +import Callout from "../../components/docs/callout.tsx"; + +Untuk membuat aplikasi menggunakan `create-t3-app`, jalankan salah satu dari tiga perintah berikut dan jawab pertanyaan dari prompt perintah: + +### npm + +```bash +npm create t3-app@latest +``` + +### yarn + +```bash +yarn create t3-app +``` + +### pnpm + +```bash +pnpm create t3-app@latest +``` + +### bun + +```bash +bun create t3-app@latest +``` + +Setelah aplikasi Anda telah dibuat, lihat langkah-langkah pertama [di sini](/id/usage/first-steps) untuk memulai aplikasi baru Anda. + +## Penggunaan Lanjutan + +| Opsi/Flag | Deskripsi | +| ----------------- | ----------------------------------------------------------------------- | +| `[dir]` | Sertakan argumen direktori dengan nama untuk proyek | +| `--noGit` | Katakan secara eksplisit kepada CLI untuk tidak menginisialisasi repo git baru di proyek | +| `-y`, `--default` | Lewati CLI dan bootstrapping aplikasi t3 baru dengan semua opsi yang dipilih | +| `--noInstall` | Hasilkan proyek tanpa menginstal dependensi | + +## Penggunaan Eksperimental + +Untuk CI kami, kami memiliki beberapa flag eksperimental yang memungkinkan Anda membuat aplikasi tanpa prompt. Jika ini berlaku untuk Anda, Anda dapat menggunakan flag-flag ini. Harap dicatat bahwa flag-flag ini bersifat eksperimental dan dapat berubah di masa depan tanpa mengikuti semver versioning. + +| Flag | Deskripsi | +| ------------ | ----------------------------------- | +| `--CI` | Beri tahu CLI bahwa Anda berada dalam mode CI | +| `--trpc` | Sertakan tRPC dalam proyek | +| `--prisma` | Sertakan Prisma dalam proyek | +| `--nextAuth` | Sertakan NextAuth.js dalam proyek | +| `--tailwind` | Sertakan Tailwind CSS dalam proyek | + + + Jika Anda tidak menyediakan flag `CI`, maka flag-flag lainnya tidak berpengaruh. + + +Anda tidak perlu secara eksplisit menolak paket yang tidak Anda inginkan. Namun, jika Anda lebih suka eksplisit, Anda dapat menyampaikan `false`, misalnya `--nextAuth false`. + +### Contoh + +Berikut ini akan membuat aplikasi T3 dengan tRPC dan Tailwind CSS. + +```bash +pnpm dlx create-t3-app@latest --CI --trpc --tailwind +``` \ No newline at end of file diff --git a/www/src/pages/id/introduction.md b/www/src/pages/id/introduction.md new file mode 100644 index 0000000000..ba53d05deb --- /dev/null +++ b/www/src/pages/id/introduction.md @@ -0,0 +1,42 @@ +--- +title: Pengantar +description: Pengantar ke Stack T3 +layout: ../../layouts/docs.astro +lang: id +--- + +
+ +
+ +## Stack T3 + +_"Stack T3"_ adalah sebuah stack pengembangan web yang dibuat oleh [Theo](https://twitter.com/t3dotgg) yang berfokus pada kesederhanaan, modularitas, dan typesafety full-stack. + +Inti dari stack ini adalah [**Next.js**](https://nextjs.org/) dan [**TypeScript**](https://typescriptlang.org/). [**Tailwind CSS**](https://tailwindcss.com/) hampir selalu disertakan. Jika Anda melakukan sesuatu yang menyerupai backend, [**tRPC**](https://trpc.io/), [**Prisma**](https://prisma.io/), dan [**NextAuth.js**](https://next-auth.js.org/) adalah tambahan yang bagus. + +Anda mungkin telah menyadari bahwa ada… banyak sekali komponen. Ini memang disengaja. Tukar masukkan komponen sesuai kebutuhan Anda - stack ini pada dasarnya adalah modular :) + +## Jadi... apa itu create-t3-app? Sebuah template? + +Semacam itu? `create-t3-app` adalah sebuah CLI yang dibangun oleh pengembang Stack T3 yang berpengalaman untuk mempermudah setup aplikasi Stack T3 yang modular. Ini berarti setiap komponen adalah opsional, dan "template" dihasilkan berdasarkan kebutuhan spesifik Anda. + +Setelah berbagai proyek dan bertahun-tahun di teknologi ini, kami memiliki banyak pendapat dan wawasan. Kami telah melakukan yang terbaik untuk mengkodekannya ke dalam CLI ini. + +Ini **BUKAN** sebuah template yang lengkap. Kami **mengharapkan** Anda membawa pustaka Anda sendiri yang memecahkan kebutuhan dari **APLIKASI ANDA**. Meskipun kami tidak ingin meresepkan solusi untuk masalah yang lebih spesifik seperti manajemen state dan penyebaran, kami [memiliki beberapa rekomendasi yang terdaftar di sini](/id/rekomendasi-lain). + +## Aksioma T3 + +Kami akan jujur - ini adalah sebuah _proyek yang beropini_. Kami berbagi sejumlah keyakinan inti seputar pembangunan dan kami memperlakukannya sebagai dasar untuk keputusan kami. + +### Memecahkan Masalah + +Mudah untuk terjebak dalam perangkap "menambahkan segalanya" - kami secara eksplisit tidak ingin melakukan itu. Segala sesuatu yang ditambahkan ke `create-t3-app` harus memecahkan masalah spesifik yang ada dalam teknologi inti yang disertakan. Ini berarti kami tidak akan menambahkan hal-hal seperti pustaka state (`zustand`, `redux`) tetapi kami akan menambahkan hal-hal seperti NextAuth.js dan mengintegrasikan Prisma dan tRPC untuk Anda. + +### Berdarah dengan Bertanggung Jawab + +Kami suka teknologi terbaru kami. Jumlah kecepatan dan, jujur saja, kesenangan yang datang dari hal-hal baru sangat keren. Kami pikir penting untuk berdarah dengan bertanggung jawab, menggunakan teknologi berisiko di bagian yang kurang berisiko. Ini berarti kami tidak akan ⛔️ bertaruh pada teknologi database baru yang berisiko (SQL itu bagus!). Tapi kami dengan senang hati ✅ bertaruh pada tRPC karena itu hanya fungsi yang mudah untuk dipindahkan. + +### Typesafety Tidak Opsional + +Tujuan yang dinyatakan dari Create T3 App adalah untuk menyediakan cara tercepat untuk memulai aplikasi web full-stack, **typesafe** yang baru. Kami mengambil typesafety secara serius di bagian ini karena meningkatkan produktivitas kami dan membantu kami mengirim lebih sedikit bug. Setiap keputusan yang mengkompromikan sifat typesafe dari Create T3 App adalah keputusan yang harus dibuat dalam proyek yang berbeda. diff --git a/www/src/pages/id/other-recs.md b/www/src/pages/id/other-recs.md new file mode 100644 index 0000000000..b2494d3b57 --- /dev/null +++ b/www/src/pages/id/other-recs.md @@ -0,0 +1,163 @@ +--- +title: Rekomendasi Lainnya +description: Perpustakaan dan Layanan yang kami rekomendasikan untuk banyak proyek +layout: ../../layouts/docs.astro +lang: id +--- + +Kami menyadari bahwa perpustakaan yang disertakan dalam `create-t3-app` tidak memecahkan setiap masalah. Meskipun kami mendorong Anda untuk memulai proyek Anda dengan apa yang kami sediakan, akan ada waktu ketika Anda perlu membawa paket lain. Hanya Anda yang bisa tahu apa yang dibutuhkan proyek Anda, tetapi berikut adalah beberapa hal yang sering kami rekomendasikan. + +Ini adalah rekomendasi oleh individu kontributor Create T3 App dan seharusnya tidak dilihat sebagai dukungan "resmi" oleh tim Create T3 App atau T3-OSS. _**Lakukan penelitian Anda sendiri, terutama sebelum berkomitmen pada layanan berbayar**_. + +## Manajemen State + +_**Catatan Editor**_: Perpustakaan manajemen state bisa bagus, tetapi seringkali tidak diperlukan. Hook React Query tRPC seharusnya dapat mengatasi state server Anda. Untuk state klien, mulailah dengan `useState` React, dan gunakan salah satu opsi ini saat Anda membutuhkan lebih banyak. + +### Zustand + +**Untuk tidak pernah menggunakan Redux lagi** + +Redux modern dan sederhana yang Anda tidak tahu Anda butuhkan. [Poimandres](https://github.com/pmndrs) selalu dapat dipercaya. Anda dapat membangun segalanya mulai dari aplikasi panggilan video hingga permainan hingga server dengan perpustakaan kecil ini. + +- [Zustand Homepage](https://zustand-demo.pmnd.rs/) +- [Zustand GitHub](https://github.com/pmndrs/zustand) + +### Jotai + +**Untuk tidak pernah menggunakan Context lagi** + +Untuk pendekatan yang lebih atomik, Jotai sulit untuk dikalahkan. Juga oleh [Poimandres](https://github.com/pmndrs), Jotai memungkinkan Anda mendefinisikan singleton yang terasa seperti useState global. Pilihan bagus untuk perilaku yang memerlukan stateful yang belum membutuhkan mesin state. + +- [Jotai Homepage](https://jotai.org/) +- [Jotai GitHub](https://github.com/pmndrs/jotai) + +## Perpustakaan Komponen + +Sebagian besar aplikasi membutuhkan beberapa komponen yang sama - tombol toggle, menu dropdown, modal, dan sebagainya. Perpustakaan ini menyediakan komponen-komponen yang bagus, dapat diakses, yang dapat Anda gunakan dan sesuaikan sesuai keinginan Anda. + +### Perpustakaan Komponen Tanpa Gaya + +Juga dikenal sebagai perpustakaan tanpa kepala, mereka menyediakan komponen yang bagus, tanpa gaya, dan dapat diakses yang dapat Anda sesuaikan sesuai keinginan Anda. Berikut beberapa rekomendasi. + +- [Radix UI](https://www.radix-ui.com/) memberikan seperangkat dasar yang nyaman dan dapat diakses yang dapat Anda gayakan dengan vanilla atau Tailwind CSS. + +- [Headless UI](https://headlessui.com/) dibuat oleh tim Tailwind CSS juga menyediakan komponen yang tidak memiliki gaya dan dapat diakses yang berintegrasi dengan sempurna dengan Tailwind CSS. + +- [React Aria](https://react-spectrum.adobe.com/react-aria/) menyediakan dasar UI yang dapat diakses untuk sistem desain Anda. Komponen Date Picker mereka adalah yang terbaik. + +### Perpustakaan Komponen Dengan Gaya + +**Untuk saat Anda hanya ingin tampilan aplikasi Anda terlihat baik** + +Kadang-kadang Anda membangun proyek di mana Anda hanya ingin tampilan UI terlihat bagus dari awal. Untuk Dasbor Admin dan proyek serupa lainnya, salah satu perpustakaan komponen ini akan menyelesaikan pekerjaan dengan baik. + +- [Chakra UI](https://chakra-ui.com) +- [Mantine](https://mantine.dev) +- [@shadcn/ui](https://ui.shadcn.com/) + +### Otoritas Varians Kelas + +**Untuk membangun Perpustakaan UI** + +Bangun Perpustakaan UI secara deklaratif dengan berbagai variasi warna, ukuran, dll. Ketika proyek Anda mencapai skala di mana Anda ingin sekumpulan komponen UI standar dengan berbagai variasi menggunakan Tailwind CSS, CVA adalah alat yang bagus. + +- [Class Variance Authority GitHub](https://github.com/joe-bell/cva) + +## Animasi + +Ketika Anda membutuhkan animasi dalam aplikasi Anda, berikut rekomendasi kami. + +### AutoAnimate + +**Untuk animasi dengan satu baris kode** + +Sebagian besar perpustakaan animasi mencoba memenuhi setiap kasus penggunaan yang mungkin, dan menjadi kikuk sebagai hasilnya. AutoAnimate adalah alat tanpa konfigurasi yang akan memberikan peningkatan yang signifikan dalam UX tanpa usaha pengembang tambahan. + +- [AutoAnimate Homepage](https://auto-animate.formkit.com/) +- [AutoAnimate GitHub](https://github.com/formkit/auto-animate) +- [Potongan Kode Komponen AutoAnimate](https://gist.github.com/hwkr/3fdea5d7f609b98c162e5325637cf3cb) + +### Framer Motion + +**Untuk animasi kompleks dengan kode yang deklaratif** + +Framer Motion menyediakan sintaksis yang sederhana dan deklaratif dan memungkinkan Anda menulis kode yang lebih sedikit untuk membuat segala sesuatu mulai dari animasi kompleks hingga gerakan. + +- [Framer Motion Homepage](https://framer.com/motion) +- [Dokumentasi Framer Motion](https://www.framer.com/docs/) + +## Penyimpanan, Infrastruktur, Basis Data, dan CI + +### Vercel + +**Untuk hosting aplikasi Anda** + +Vercel mengatasi masalah penyebaran web dan membuatnya menjadi integrasi GitHub yang dapat diatur dan dilupakan. Kami telah mengskalakan hingga ratusan ribu pengguna tanpa masalah. Berbasis AWS, hanya memiliki antarmuka yang lebih baik :) + +- [Vercel Homepage](https://vercel.com/) +- [Panduan penyebaran Create T3 App Vercel](/id/deployment/vercel) + +### PlanetScale + +**Untuk basis data tanpa kekhawatiran** + +PlanetScale adalah platform "basis data serverless" terbaik yang pernah kami gunakan. Skala yang luar biasa, pengalaman pengembang yang hebat, dan harga fantastis. Jika Anda menggunakan SQL (dan semoga Prisma), ini sulit untuk dikalahkan. + +- [PlanetScale Homepage](https://planetscale.com/) + +### Railway + +**Untuk hosting infrastruktur Anda** + +"Heroku Modern". Cara termudah untuk mendapatkan server nyata yang berfungsi. Jika Vercel dan PlanetScale belum cukup, Railway mungkin akan cocok. Tunjukkannya ke repositori GitHub dan jalankan. + +- [Railway Homepage](https://railway.app/) + +### Upstash + +**Untuk Redis serverless** + +Kami suka Prisma dan PlanetScale, tetapi beberapa proyek memerlukan solusi yang lebih cepat. Upstash memungkinkan Anda mendapatkan kinerja in-memory Redis dalam proyek serverless Anda, tanpa harus mengelola infrastruktur dan penyesuaian sendiri. + +- [Upstash Homepage](https://upstash.com/) + +### Pusher + +**Untuk WebSockets serverless** + +Jika WebSockets menjadi fokus utama proyek Anda, Anda mungkin ingin mempertimbangkan backend yang lebih tradisional seperti [Fastify](https://www.fastify.io/) (yang [juga bekerja dengan tRPC!](https://trpc.io/docs/v10/fastify)). Tetapi jika Anda ingin dengan cepat menambahkan WebSockets ke T3 App, Pusher adalah pilihan yang sangat baik. + +- [Pusher Homepage](https://pusher.com/) + +### Soketi + +Soketi adalah alternatif self-hostable, sederhana, dan cepat untuk Pusher. Ini sepenuhnya kompatibel dengan SDK Pusher yang dapat Anda gunakan untuk terhubung ke server. Soketi serverless juga dalam versi beta. + +- [Soketi Homepage](https://soketi.app) +- [Soketi GitHub](https://github.com/soketi/soketi) + +## Analitik + +Data pengguna sangat berharga saat Anda membangun aplikasi. Berikut beberapa penyedia analitik yang kami rekomendasikan. + +### Plausible + +Butuh analitik? Plausible adalah salah satu cara tercepat untuk mendapatkannya. Sangat minimalis. Bahkan memiliki [plugin sederhana untuk Next.js](https://plausible.io/docs/proxy/guides/nextjs). + +- [Plausible Homepage](https://plausible.io/) + +### Umami + +Umami adalah alternatif Google Analytics yang open-source, dapat di-hosting sendiri, sederhana, cepat, dan berfokus pada privasi. Anda dapat dengan mudah mendeploynya ke Vercel, Railway, dll. dengan PlanetScale sebagai basis datanya atau Anda juga bisa menggunakan versi cloudnya. + +- [Umami Homepage](https://umami.is/) +- [Umami GitHub](https://github.com/umami-software/umami) +- [Umami Cloud](https://cloud.umami.is/) + +## Lainnya + +### Next Bundle Analyzer + +Terkadang sulit untuk menentukan apa yang akan disertakan dalam output build aplikasi Anda. Next Bundle Analyzer adalah cara mudah untuk memvisualisasikan dan menganalisis bundel JavaScript yang dihasilkan. + +- [@next/bundle-analyzer di npm](https://www.npmjs.com/package/@next/bundle-analyzer) diff --git a/www/src/pages/id/t3-collection.mdx b/www/src/pages/id/t3-collection.mdx new file mode 100644 index 0000000000..e53af25841 --- /dev/null +++ b/www/src/pages/id/t3-collection.mdx @@ -0,0 +1,29 @@ +--- +title: Koleksi T3 +description: Proyek open source keren dan perusahaan yang menggunakan stack T3 +layout: ../../layouts/docs.astro +lang: id +isMdx: true +--- + +import OpenSourceAppList from "../../components/docs/openSourceAppList.tsx"; +import CompanyList from "../../components/docs/companyList.tsx"; +import Callout from "../../components/docs/callout.tsx"; + +Membuat proyek menggunakan stack T3 dan ingin membagikannya? Tambahkan ke daftar! + +## Aplikasi Open Source yang dibuat menggunakan Stack T3 + + + +## Perusahaan yang menggunakan Stack T3 + +Kami sangat ingin tahu perusahaan mana saja yang menggunakan stack T3 untuk aplikasi mereka. Apakah perusahaan Anda menggunakan stack T3 dan ingin membagikannya? Tambahkan ke daftar! + + + + + Punya proyek keren yang menggunakan stack T3? Buat sebuah [pull + request](https://github.com/t3-oss/create-t3-app/tree/next/www/src/components/docs/openSourceAppList.tsx) + dan tambahkan di sini! + diff --git a/www/src/pages/id/usage/drizzle.mdx b/www/src/pages/id/usage/drizzle.mdx new file mode 100644 index 0000000000..14102afa6f --- /dev/null +++ b/www/src/pages/id/usage/drizzle.mdx @@ -0,0 +1,14 @@ +--- +title: Drizzle +description: Penggunaan Drizzle +layout: ../../../layouts/docs.astro +lang: id +isMdx: true +--- + +import Callout from "../../../components/docs/callout.tsx"; + + + Opsi `drizzle` adalah tambahan baru dan belum ada dokumentasi yang tersedia. Kontribusi sangat kami harapkan! + + diff --git a/www/src/pages/id/usage/env-variables.mdx b/www/src/pages/id/usage/env-variables.mdx new file mode 100644 index 0000000000..5043cdea8a --- /dev/null +++ b/www/src/pages/id/usage/env-variables.mdx @@ -0,0 +1,149 @@ +--- +title: Variabel Lingkungan +description: Memulai dengan Create T3 App +layout: ../../../layouts/docs.astro +lang: id +isMdx: true +--- + +import Callout from "../../../components/docs/callout.tsx"; + +Create T3 App menggunakan paketnya sendiri [@t3-oss/env-nextjs](https://env.t3.gg) bersama dengan [zod](https://zod.dev) di bawahnya untuk memvalidasi variabel lingkungan baik saat runtime _maupun_ buildtime dengan menyediakan logika sederhana di `src/env.mjs`. + +## env.mjs + +_TLDR; Jika Anda ingin menambahkan variabel lingkungan baru, Anda harus menambahkan validator untuknya di `src/env.mjs`, dan kemudian tambahkan pasangan KV di `.env`_ + +```ts:env.mjs +import { createEnv } from "@t3-oss/env-nextjs"; +import { z } from "zod"; + +export const env = createEnv({ + server: { + NODE_ENV: z.enum(["development", "test", "production"]), + }, + client: { + // NEXT_PUBLIC_CLIENTVAR: z.string(), + }, + runtimeEnv: { + NODE_ENV: process.env.NODE_ENV, + }, +}); +``` + +T3 Env menggunakan fungsi `createEnv` untuk membuat skema yang memvalidasi variabel lingkungan baik di sisi klien maupun sisi server. + + + Untuk informasi lebih lanjut tentang bagaimana `createEnv` bekerja secara internal, lihat [Dokumentasi T3 Env](https://env.t3.gg/docs/introduction) + + +## Menggunakan Variabel Lingkungan + +Ketika Anda ingin menggunakan variabel lingkungan Anda, Anda dapat mengimpornya dari `env.mjs` yang telah dibuat dan menggunakannya seperti biasanya. Jika Anda mengimpor ini di sisi klien dan mencoba mengakses variabel lingkungan sisi server, Anda akan mendapatkan kesalahan saat runtime. + +```ts:pages/api/hello.ts +import { env } from "../../env.mjs"; + +// `env` sepenuhnya aman tipe dan memberikan autokomplet +const dbUrl = env.DATABASE_URL; +``` + +```ts:pages/index.tsx +import { env } from "../env.mjs"; + +// ❌ Ini akan menyebabkan kesalahan saat runtime +const dbUrl = env.DATABASE_URL; + +// ✅ Ini baik-baik saja +const wsKey = env.NEXT_PUBLIC_WS_KEY; +``` + +## .env.example + +Karena file `.env` default tidak di-commit ke kontrol versi, kami juga menyertakan file `.env.example`, di mana Anda dapat menyimpan salinan file `.env` Anda dengan menghapus segala rahasia. Ini tidak diwajibkan, tetapi kami merekomendasikan agar Anda selalu memperbarui contoh ini agar memudahkan kontributor untuk memulai dengan lingkungan mereka. + +Beberapa kerangka kerja dan alat pengembangan, seperti Next.js, menyarankan Anda untuk menyimpan rahasia dalam file `.env.local` dan meng-commit file `.env` ke proyek Anda. Ini tidak direkomendasikan, karena bisa mempermudah pengiriman rahasia secara tidak sengaja ke proyek Anda. Sebaliknya, kami merekomendasikan agar Anda menyimpan rahasia dalam file `.env`, menyimpan file `.env` Anda di `.gitignore`, dan hanya meng-commit file `.env.example` ke proyek Anda. + +## Menambahkan Variabel Lingkungan + +Untuk memastikan bahwa proses build Anda tidak pernah selesai tanpa variabel lingkungan yang diperlukan oleh proyek, Anda perlu menambahkan variabel lingkungan baru di **dua** lokasi: + +📄 `.env`: Masukkan variabel lingkungan Anda seperti biasanya dalam file `.env`, yaitu `KEY=VALUE` + +📄 `env.mjs`: Tambahkan logika validasi yang sesuai untuk variabel lingkungan dengan mendefinisikan skema Zod di dalam `createEnv` untuk masing-masingnya, misalnya `KEY: z.string()`. Selain itu, pastikan untuk mendestruksi variabel tersebut di opsi `runtimeEnv`, misalnya: `KEY: process.env.KEY` + + + Mengapa saya perlu mendestruksi variabel lingkungan di `runtimeEnv`? + Ini disebabkan oleh bagaimana Next.js menggabungkan variabel lingkungan di beberapa runtime tertentu. + Dengan mendestruksi secara manual, Anda memastikan bahwa variabel tersebut tidak akan dihilangkan dari bundel. + + +Opsionalnya, Anda juga dapat menjaga agar `.env.example` tetap terbaru: + +📄 `.env.example`: Masukkan variabel lingkungan Anda, tetapi pastikan untuk tidak menyertakan nilai jika itu adalah rahasia, yaitu `KEY=VALUE` atau `KEY=` + +### Contoh + +_Saya ingin menambahkan Token API Twitter saya sebagai variabel lingkungan sisi server_ + +1. Tambahkan variabel lingkungan ke dalam `.env`: + +``` +TWITTER_API_TOKEN=1234567890 +``` + +2. Tambahkan variabel lingkungan ke dalam `env.mjs`: + +```ts +import { createEnv } from "@t3-oss/env-nextjs"; +import { z } from "zod"; + +export const env = createEnv({ + server: { + TWITTER_API_TOKEN: z.string(), + }, + // ... + runtimeEnv: { + // ... + TWITTER_API_TOKEN: process.env.TWITTER_API_TOKEN, + }, +}); +``` + +3. _Opsional:_ Tambahkan variabel lingkungan ke dalam `.env.example` dan pastikan untuk tidak menyertakan rahasia di opsi `runtimeEnv` + +```bash +TWITTER_API_TOKEN= +``` + +## Konversi Tipe + +Semua variabel yang Anda tambahkan ke dalam `.env` akan diimpor sebagai string, bahkan jika nilainya dimaksudkan untuk mewakili tipe yang berbeda. Jika Anda ingin menggunakan variabel lingkungan Anda sebagai tipe yang berbeda saat runtime, Anda dapat menggunakan `coerce` dari Zod untuk mengonversi string ke tipe yang Anda inginkan. Ini akan melempar kesalahan jika konversi gagal. + +Tambahkan variabel ke dalam `.env` Anda: + +``` +SOME_NUMBER=123 +SOME_BOOLEAN=true +``` + +Kemudian, validasi dalam `env.mjs`: + +```ts +import { createEnv } from "@t3-oss/env-nextjs"; +import { z } from "zod"; + +export const env = createEnv({ + server: { + SOME_NUMBER: z.coerce.number(), + + + SOME_BOOLEAN: z.coerce.boolean(), + }, + // ... + runtimeEnv: { + SOME_NUMBER: process.env.SOME_NUMBER, + SOME_BOOLEAN: process.env.SOME_BOOLEAN, + }, +}); +``` \ No newline at end of file diff --git a/www/src/pages/id/usage/first-steps.md b/www/src/pages/id/usage/first-steps.md new file mode 100644 index 0000000000..a614c34081 --- /dev/null +++ b/www/src/pages/id/usage/first-steps.md @@ -0,0 +1,50 @@ +--- +title: Langkah Pertama +description: Memulai dengan Aplikasi T3 Baru Anda +layout: ../../../layouts/docs.astro +lang: id +--- + +Anda baru saja membuat kerangka dasar aplikasi T3 baru dan siap untuk mulai. Berikut adalah langkah-langkah dasar untuk membuat aplikasi Anda berfungsi. + +## Database + +### Prisma + +Jika aplikasi Anda menggunakan Prisma, pastikan untuk menjalankan `npx prisma db push` dari direktori root aplikasi Anda. Perintah ini akan menyinkronkan skema Prisma Anda dengan database Anda dan akan menghasilkan jenis TypeScript untuk Prisma Client berdasarkan skema Anda. Perhatikan bahwa Anda perlu [memulai ulang server TypeScript](https://tinytip.co/tips/vscode-restart-ts/) setelah melakukan ini agar dapat mendeteksi jenis yang dihasilkan. + +### Drizzle + +Jika aplikasi Anda menggunakan Drizzle, periksa file `.env` untuk petunjuk tentang bagaimana membuat variabel lingkungan `DATABASE_URL` Anda. Setelah file lingkungan Anda siap, jalankan `pnpm db:push` (atau yang setara untuk manajer paket lainnya) untuk mengirimkan skema Anda. + +## Otentikasi + +Jika aplikasi Anda menggunakan NextAuth.js, kami memulai dengan `DiscordProvider`. Ini adalah salah satu penyedia paling sederhana yang ditawarkan oleh NextAuth.js, tetapi masih memerlukan sedikit setup awal dari Anda. + +Tentu saja, jika Anda lebih suka menggunakan penyedia otentikasi yang berbeda, Anda juga dapat menggunakan salah satu [banyak penyedia](https://next-auth.js.org/providers/) yang ditawarkan oleh NextAuth.js. + +1. Anda akan memerlukan akun Discord, jadi daftarkan satu jika Anda belum memiliki akun. +2. Buka dan klik "Aplikasi Baru" di sudut kanan atas. Beri nama aplikasi Anda dan setujui Ketentuan Layanan. +3. Setelah aplikasi Anda dibuat, buka "Pengaturan → OAuth2 → Umum". +4. Salin "Client ID" dan tambahkan ke file `.env` Anda sebagai `DISCORD_CLIENT_ID`. +5. Klik "Reset Secret", salin rahasia baru, dan tambahkan ke file `.env` Anda sebagai `DISCORD_CLIENT_SECRET`. +6. Klik "Tambahkan Redirect" dan ketik `http://localhost:3000/api/auth/callback/discord`. + - Untuk implementasi produksi, ikuti langkah-langkah sebelumnya untuk membuat Aplikasi Discord lainnya, tetapi kali ini gantilah `http://localhost:3000` dengan URL tempat Anda akan mendeploy aplikasi Anda. +7. Simpan Perubahan. +8. Tetapkan `NEXTAUTH_SECRET` di dalam file `.env`. Di dalam pengembangan, setiap string akan berfungsi, untuk produksi lihat catatan di dalam file `.env` tentang cara menghasilkan rahasia yang aman. + +Anda sekarang seharusnya dapat masuk. + +## Pengaturan Editor + +Berikut adalah ekstensi yang direkomendasikan untuk pengalaman pengembangan yang optimal. Tautan di bawah ini menyediakan dukungan plugin yang spesifik untuk editor. + +- [Ekstensi Prisma](https://www.prisma.io/docs/guides/development-environment/editor-setup) +- [Ekstensi Tailwind CSS IntelliSense](https://tailwindcss.com/docs/editor-setup) +- [Ekstensi Prettier](https://prettier.io/docs/en/editors.html) + +## Langkah Selanjutnya + +- Jika aplikasi Anda mencakup tRPC, periksa `src/pages/index.tsx` dan `src/server/api/routers/post.ts` untuk melihat bagaimana kueri tRPC bekerja. +- Jelajahi dokumen Create T3 App, serta dokumen paket-paket yang digunakan oleh aplikasi Anda. +- Bergabunglah dengan [Discord](https://t3.gg/discord) kami dan berikan kami bintang di [GitHub](https://github.com/t3-oss/create-t3-app)! :) diff --git a/www/src/pages/id/usage/index.astro b/www/src/pages/id/usage/index.astro new file mode 100644 index 0000000000..8260ab7530 --- /dev/null +++ b/www/src/pages/id/usage/index.astro @@ -0,0 +1,26 @@ +--- +import IndexPage from "../../../components/docs/indexPage.astro"; +import { SIDEBAR, type Frontmatter } from "../../../config"; +import { getLanguageFromURL } from "../../../languages"; +import Layout from "../../../layouts/docs.astro"; + +const frontmatter: Frontmatter = { + title: "Pemakaian", + layout: "docs", + // description: "Learn how to use the different technology from the T3 Stack.", + description: + "Pelajari bagaimana cara memakai berbagai teknologi dari Stack T3.", +}; + +const lang = getLanguageFromURL(Astro.url.pathname); +const sidebarEntries = SIDEBAR[lang]["Usage"]!; +const files = await Astro.glob("./*.{md,mdx,astro}"); +--- + + + + diff --git a/www/src/pages/id/usage/next-auth.mdx b/www/src/pages/id/usage/next-auth.mdx new file mode 100644 index 0000000000..0e00d68725 --- /dev/null +++ b/www/src/pages/id/usage/next-auth.mdx @@ -0,0 +1,230 @@ +--- +title: NextAuth.js +description: Penggunaan NextAuth.js +layout: ../../../layouts/docs.astro +lang: id +isMdx: true +--- + +import Callout from "../../../components/docs/callout.tsx"; + +Ketika Anda memerlukan sistem otentikasi dalam aplikasi Next.js Anda, NextAuth.js adalah solusi yang sangat baik untuk membawa kompleksitas keamanan tanpa kerumitan dalam membangunnya sendiri. Ini dilengkapi dengan daftar penyedia yang luas untuk dengan cepat menambahkan otentikasi OAuth dan menyediakan adapter untuk banyak basis data dan ORM. + +## Penyedia Konteks + +Di entri titik aplikasi Anda, Anda akan melihat bahwa aplikasi Anda dibungkus dalam [SessionProvider](https://next-auth.js.org/getting-started/client#sessionprovider): + +```tsx:pages/_app.tsx + + + +``` + +Penyedia konteks ini memungkinkan aplikasi Anda mengakses data sesi dari mana saja dalam aplikasi Anda, tanpa perlu melewatkan data tersebut sebagai prop: + +```tsx:pages/users/[id].tsx +import { useSession } from "next-auth/react"; + +const User = () => { + const { data: session } = useSession(); + + if (!session) { + // Tangani kondisi belum terotentikasi, misalnya render komponen SignIn + return ; + } + + return

Selamat datang {session.user.name}!

; +}; +``` + +## Mengambil Sesi di Sisi Server + +Terkadang Anda mungkin ingin meminta sesi di sisi server. Untuk melakukannya, prefetch sesi menggunakan fungsi bantuan `getServerAuthSession` yang disediakan oleh `create-t3-app`, dan teruskan ke klien menggunakan `getServerSideProps`: + +```tsx:pages/users/[id].tsx +import { getServerAuthSession } from "../server/auth"; +import { type GetServerSideProps } from "next"; + +export const getServerSideProps: GetServerSideProps = async (ctx) => { + const session = await getServerAuthSession(ctx); + return { + props: { session }, + }; +}; + +const User = () => { + const { data: session } = useSession(); + // CATATAN: `session` tidak akan memiliki status loading karena sudah diambil di sisi server + + ... +} +``` + +## Penyertakan `user.id` pada Sesi + +Create T3 App dikonfigurasi untuk menggunakan [session callback](https://next-auth.js.org/configuration/callbacks#session-callback) dalam konfigurasi NextAuth.js untuk menyertakan ID pengguna dalam objek `session`. + +```ts:server/auth.ts +callbacks: { + session({ session, user }) { + if (session.user) { + session.user.id = user.id; + } + return session; + }, + }, +``` + +Ini dikaitkan dengan file deklarasi tipe untuk memastikan `user.id` dijelaskan saat diakses pada objek `session`. Baca lebih lanjut tentang [`Module Augmentation`](https://next-auth.js.org/getting-started/typescript#module-augmentation) di dokumen NextAuth.js. + +```ts:server/auth.ts +import { DefaultSession } from "next-auth"; + +declare module "next-auth" { + interface Session { + user?: { + id: string; + } & DefaultSession["user"]; + } +} +``` + +Pola yang sama dapat digunakan untuk menambahkan data lain ke objek `session`, seperti bidang `role`, tetapi **tidak boleh disalahgunakan untuk menyimpan data sensitif** pada klien. + +## Penggunaan dengan tRPC + +Ketika menggunakan NextAuth.js dengan tRPC, Anda dapat membuat prosedur yang dapat digunakan kembali dan dilindungi dengan menggunakan [middleware](https://trpc.io/docs/v10/middlewares). Ini memungkinkan Anda membuat prosedur yang hanya dapat diakses oleh pengguna yang terotentikasi. `create-t3-app` menyiapkan semua ini untuk Anda, memungkinkan Anda dengan mudah mengakses objek sesi dalam prosedur yang terotentikasi. + +Ini dilakukan dalam dua langkah: + +1. Ambil sesi dari header permintaan menggunakan fungsi bantuan [`getServerSession`](https://next-auth.js.org/configuration/nextjs#getServerSession). Keuntungan menggunakan `getServerSession` daripada `getSession` biasa adalah bahwa ini adalah fungsi hanya sisi server dan tidak memicu panggilan pengambilan yang tidak perlu. `create-t3-app` membuat fungsi bantuan yang mengabstraksi API khusus ini agar Anda tidak perlu mengimpor opsi NextAuth.js serta fungsi `getServerSession` setiap kali Anda perlu mengakses sesi. + +```ts:server/auth.ts +export const getServerAuthSession = (ctx: { + req: GetServerSidePropsContext["req"]; + res: GetServerSidePropsContext["res"]; +}) => { + return getServerSession(ctx.req, ctx.res, authOptions); +}; +``` + +Dengan menggunakan fungsi bantuan ini, kita dapat mengambil sesi dan meneruskannya ke konteks tRPC: + +```ts:server/api/trpc.ts +import { getServerAuthSession } from "../auth"; + +export const createContext = async (opts: CreateNextContextOptions) => { + const { req, res } = opts; + const session = await getServerAuthSession({ req, res }); + return await createContextInner({ + session, + }); +}; +``` + +2. Buat middleware tRPC yang memeriksa apakah pengguna terotentikasi. Kemudian kita menggunakan middleware dalam `protectedProcedure`. Setiap pemanggilan ke prosedur ini harus terotentikasi, jika tidak, akan terjadi kesalahan yang dapat ditangani dengan tepat oleh klien. + +```ts:server/api/trpc.ts +const isAuthed = t.middleware(({ ctx, next }) => { + if (!ctx.session || !ctx.session.user) { + throw new TRPCError({ code: "UNAUTHORIZED" }); + } + return next({ + ctx: { + // memastikan bahwa `session` tidak dapat bernilai null + session: { ...ctx.session, user: ctx.session.user }, + }, + }); +}); + +export const protectedProcedure = t.procedure.use(isAuthed); +``` + +Objek sesi adalah representasi ringan dan minimal dari pengguna dan hanya berisi beberapa bidang. Saat menggunakan `protectedProcedures`, Anda memiliki akses ke id pengguna yang dapat digunakan untuk mengambil lebih banyak data dari basis data. + +```ts:server/api/routers/user.ts +const userRouter = router({ + me: protectedProcedure.query(async ({ ctx }) => { + const user = await prisma.user.findUnique({ + where: { + id: ctx + +.session.user.id, + }, + }); + return user; + }), +}); +``` + +## Penggunaan dengan Prisma + +Menggunakan NextAuth.js dengan Prisma memerlukan banyak [pengaturan awal](https://authjs.dev/reference/adapter/prisma/). `create-t3-app` menangani semua ini untuk Anda, dan jika Anda memilih baik Prisma maupun NextAuth.js, Anda akan mendapatkan sistem otentikasi yang sepenuhnya berfungsi dengan semua model yang diperlukan telah dikonfigurasi sebelumnya. Kami mengirimkan aplikasi kerangka Anda dengan penyedia OAuth Discord yang telah dikonfigurasi sebelumnya, yang kami pilih karena merupakan salah satu yang paling mudah untuk memulai - cukup berikan token Anda di `.env` dan Anda siap untuk mulai. Namun, Anda dengan mudah dapat menambahkan penyedia lain dengan mengikuti [dokumen NextAuth.js](https://next-auth.js.org/providers/). Perhatikan bahwa beberapa penyedia memerlukan penambahan bidang tambahan ke beberapa model tertentu. Kami sarankan Anda membaca dokumentasi penyedia yang ingin Anda gunakan untuk memastikan Anda memiliki semua bidang yang diperlukan. + +### Menambahkan Bidang Baru ke Model Anda + +Ketika menambahkan bidang baru ke salah satu model `User`, `Account`, `Session`, atau `VerificationToken` (kemungkinan besar Anda hanya perlu memodifikasi model `User`), Anda perlu mempertimbangkan bahwa [adapter Prisma](https://next-auth.js.org/adapters/prisma) secara otomatis membuat bidang pada model-model ini ketika pengguna baru mendaftar dan masuk. Oleh karena itu, ketika menambahkan bidang baru ke model-model ini, Anda harus memberikan nilai default untuk mereka, karena adapter tidak menyadari bidang-bidang ini. + +Contohnya, jika Anda ingin menambahkan bidang `role` ke model `User`, Anda perlu memberikan nilai default untuk bidang `role` dalam model `User` dengan menambahkan nilai `@default` ke bidang `role` dalam model `User`: + +```diff:prisma/schema.prisma ++ enum Role { ++ USER ++ ADMIN ++ } + + model User { + ... ++ role Role @default(USER) + } +``` + +## Penggunaan dengan Middleware Next.js + +Penggunaan NextAuth.js dengan middleware Next.js [memerlukan penggunaan strategi sesi JWT](https://next-auth.js.org/configuration/nextjs#caveats) untuk otentikasi. Hal ini karena middleware hanya dapat mengakses cookie sesi jika itu adalah JWT. Secara default, Create T3 App dikonfigurasi untuk menggunakan strategi basis data **default**, berpadu dengan Prisma sebagai adapter basis data. + + + Menggunakan sesi basis data adalah pendekatan yang direkomendasikan dan Anda sebaiknya membaca tentang JWT sebelum beralih ke strategi sesi JWT untuk menghindari masalah keamanan apa pun. + + +Setelah beralih ke strategi sesi JWT, pastikan untuk memperbarui panggilan `session` di `src/server/auth.ts`. +Objek `user` akan menjadi `undefined`. Sebaliknya, ambil ID pengguna dari objek `token`. +Contohnya: + +```diff:server/auth.ts + export const authOptions: NextAuthOptions = { ++ session: { ++ strategy: "jwt", ++ }, + callbacks: { +- session: ({ session, user }) => ({ ++ session: ({ session, token }) => ({ + ...session, + user: { + ...session.user, +- id: user.id; ++ id: token.sub; + } + }), + }, + }; +``` + +## Menyiapkan Default DiscordProvider + +1. Buka [bagian Aplikasi di Portal Pengembang Discord](https://discord.com/developers/applications), dan klik "Aplikasi Baru" +2. Di menu pengaturan, pergi ke "OAuth2 => Umum" + +- Salin Client ID dan tempelkan di `DISCORD_CLIENT_ID` di `.env`. +- Di bawah Client Secret, klik "Reset Secret" dan salin string tersebut ke `DISCORD_CLIENT_SECRET` di `.env`. Hati-hati karena Anda tidak akan bisa melihat rahasia ini lagi, dan meresetnya akan menyebabkan yang lama kedaluwarsa. +- Klik "Tambahkan Redirect" dan tempelkan `/api/auth/callback/discord` (contoh untuk pengembangan lokal: http://localhost:3000/api/auth/callback/discord) +- Simpan perubahan Anda +- Mungkin, tetapi tidak disarankan, untuk menggunakan Aplikasi Discord yang sama untuk pengembangan dan produksi. Anda juga dapat mempertimbangkan [Menggantikan Provider](https://github.com/trpc/trpc/blob/main/examples/next-prisma-websockets-starter/src/pages/api/auth/%5B...nextauth%5D.ts) selama pengembangan. + +## Sumber Daya Berguna + +| Sumber Daya | Tautan | +| ------------------------------ | ------------------------------------------- | +| Dokumen NextAuth.js | https://next-auth.js.org/ | +| GitHub NextAuth.js | https://github.com/nextauthjs/next-auth | +| tRPC Kitchen Sink - dengan NextAuth | https://kitchen-sink.trpc.io/next-auth | \ No newline at end of file diff --git a/www/src/pages/id/usage/next-js.md b/www/src/pages/id/usage/next-js.md new file mode 100644 index 0000000000..64a19fca44 --- /dev/null +++ b/www/src/pages/id/usage/next-js.md @@ -0,0 +1,37 @@ +--- +title: Next.js +description: Penggunaan Next.js +layout: ../../../layouts/docs.astro +lang: id +--- + +Next.js adalah framework backend untuk aplikasi React Anda. + +
+ +
+ +Lihat [presentasi Theo tentang Next.js Conf](https://www.youtube.com/watch?v=W4UhNo3HAMw) untuk mendapatkan pemahaman yang lebih baik tentang apa itu Next.js dan bagaimana cara kerjanya.

+ +## Mengapa Harus Menggunakannya? + +Kami mencintai React. Ini telah membuat pengembangan UI dapat diakses dengan cara yang belum pernah kami bayangkan sebelumnya. Ini juga dapat membimbing pengembang ke jalur yang sulit. Next.js menawarkan pendekatan yang sedikit berpendapat dan sangat dioptimalkan untuk membuat aplikasi menggunakan React. Mulai dari routing hingga definisi API hingga rendering gambar, kami percayakan Next.js untuk membimbing pengembang menuju keputusan yang baik. + +Menggabungkan Next.js dengan [Vercel](https://vercel.com/) membuat pengembangan dan penyebaran aplikasi web lebih mudah daripada sebelumnya. Paket gratis mereka yang sangat murah hati dan antarmuka yang sangat intuitif menyediakan solusi klik-dan-pilih untuk mendeploy situs Anda (Kami ❤️ Vercel) + +## Dapatkan Static/Server Props + +Salah satu fitur utama Next.js adalah kemampuan pengambilan data. Kami sangat menyarankan untuk membaca [dokumentasi resmi](https://nextjs.org/docs/basic-features/data-fetching) untuk memahami cara menggunakan setiap metode dan bagaimana perbedaannya. `getServerSideProps` umumnya tidak disarankan kecuali ada alasan yang baik, karena itu adalah panggilan pemblokiran dan akan melambatkan situs Anda. [Incremental Static Regeneration](https://nextjs.org/docs/basic-features/data-fetching/incremental-static-regeneration) adalah alternatif yang bagus untuk `getServerSideProps` ketika data bersifat dinamis dan dapat diambil secara bertahap. + +Jika Anda perlu menggunakan fitur ini, periksa tautan-tautan berikut: [Advanced tRPC - Pemanggil, fungsi, dan gSSP](https://www.youtube.com/watch?v=G2ZzmgShHgQ) dan [SSG-Helpers](https://trpc.io/docs/v9/ssg-helpers) + +## Sumber Daya Berguna + +| Sumber Daya | Tautan | +| ------------------------------ | ------------------------------------ | +| Dokumentasi Next.js | | +| GitHub Next.js | | +| Blog Next.js | | +| Discord Next.js | | +| Twitter Next.js | | +| Saluran YouTube Vercel/Next.js | | diff --git a/www/src/pages/id/usage/prisma.md b/www/src/pages/id/usage/prisma.md new file mode 100644 index 0000000000..a565d62394 --- /dev/null +++ b/www/src/pages/id/usage/prisma.md @@ -0,0 +1,78 @@ +--- +title: Prisma +description: Penggunaan Prisma +layout: ../../../layouts/docs.astro +lang: id +--- + +Prisma adalah ORM untuk TypeScript, yang memungkinkan Anda untuk mendefinisikan skema database dan model Anda dalam file `schema.prisma`, dan kemudian menghasilkan klien yang aman untuk digunakan dalam interaksi dengan database dari backend Anda. + +## Prisma Client + +Terletak di `src/server/db.ts`, Prisma Client diinisiasi sebagai variabel global (sebagaimana yang direkomendasikan sebagai [best practice](https://www.prisma.io/docs/guides/database/troubleshooting-orm/help-articles/nextjs-prisma-client-dev-practices#problem) oleh tim Prisma) dan diekspor untuk digunakan dalam rute API Anda. Kami menyertakan Prisma Client di dalam [Konteks](/id/usage/trpc#-serverapitrpcts) secara default dan merekomendasikan penggunaan ini daripada mengimpornya secara terpisah di setiap file. + +## Skema + +Anda akan menemukan file skema Prisma di `/prisma/schema.prisma`. File ini adalah tempat Anda mendefinisikan skema database dan model Anda, dan digunakan saat menghasilkan Prisma Client. + +### Dengan NextAuth.js + +Ketika Anda memilih NextAuth.js dalam kombinasi dengan Prisma, file skema dihasilkan dan disiapkan untuk Anda dengan nilai-nilai rekomendasi untuk model `User`, `Session`, `Account`, dan `VerificationToken`, sesuai dengan [dokumentasi NextAuth.js](https://next-auth.js.org/adapters/prisma). + +## Basis Data Default + +Basis data default adalah basis data SQLite, yang bagus untuk pengembangan dan membuat prototipe dengan cepat, tetapi tidak disarankan untuk produksi. Anda dapat mengubah basis data yang digunakan dengan mengganti `provider` dalam blok `datasource` menjadi `postgresql` atau `mysql`, dan kemudian memperbarui string koneksi dalam variabel lingkungan untuk mengarahkan ke basis data Anda. + +## Menyemaikan Basis Data Anda + +[Menyemaikan basis data Anda](https://www.prisma.io/docs/guides/database/seed-database) adalah cara yang bagus untuk dengan cepat mengisi basis data Anda dengan data uji untuk membantu Anda memulai. Untuk menyiapkan penyemaian, Anda perlu membuat file `seed.ts` di direktori `/prisma`, dan kemudian menambahkan skrip `seed` ke file `package.json` Anda. Anda juga memerlukan beberapa runner TypeScript yang dapat menjalankan skrip penyemaian tersebut. Kami merekomendasikan [tsx](https://github.com/esbuild-kit/tsx), yang merupakan runner TypeScript yang sangat performant yang menggunakan esbuild dan tidak memerlukan konfigurasi ESM apa pun, tetapi `ts-node` atau runner lainnya juga akan berfungsi. + +```jsonc:package.json +{ + "scripts": { + "db-seed": "NODE_ENV=development prisma db seed" + }, + "prisma": { + "seed": "tsx prisma/seed.ts" + } +} +``` + +```ts:prisma/seed.ts +import { prisma } from "../src/server/db"; + +async function main() { + const id = "cl9ebqhxk00003b600tymydho"; + await prisma.example.upsert({ + where: { + id, + }, + create: { + id, + }, + update: {}, + }); +} + +main() + .then(async () => { + await prisma.$disconnect(); + }) + .catch(async (e) => { + console.error(e); + await prisma.$disconnect(); + process.exit(1); + }); +``` + +Kemudian, cukup jalankan `pnpm db-seed` (atau `npm`/`yarn`) untuk menyemai basis data Anda. + +## Sumber Daya Berguna + +| Sumber Daya | Tautan | +| --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | +| Dokumentasi Prisma | | +| GitHub Prisma | | +| Prisma Migrate Playground | | +| Adapter Prisma NextAuth.JS | | +| Panduan Koneksi Planetscale | | diff --git a/www/src/pages/id/usage/tailwind.md b/www/src/pages/id/usage/tailwind.md new file mode 100644 index 0000000000..3a5dd099f6 --- /dev/null +++ b/www/src/pages/id/usage/tailwind.md @@ -0,0 +1,96 @@ +--- +title: Tailwind CSS +description: Penggunaan Tailwind CSS +layout: ../../../layouts/docs.astro +lang: id +--- + +## Apa itu Tailwind CSS? + +Tailwind CSS adalah kerangka kerja CSS [bertumpu pada utilitas](https://tailwindcss.com/docs/utility-first) kecil untuk membangun desain kustom tanpa perlu beralih konteks seperti yang biasa dilakukan dalam CSS biasa. Ini adalah kerangka kerja CSS murni dan tidak menyediakan komponen atau logika pra-dibangun, serta menyediakan [seperangkat manfaat yang sangat berbeda](https://www.youtube.com/watch?v=CQuTF-bkOgc) dibandingkan dengan pustaka komponen seperti Material UI. + +Tailwind CSS membuat penulisan CSS menjadi sangat mudah dan cepat, seperti yang ditunjukkan oleh contoh berikut: + +CSS Lama: + +1. Tulis CSS, seringkali di file terpisah + +```css +.my-class { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + background-color: #fff; + border: 1px solid #e2e8f0; + border-radius: 0.25rem; + padding: 1rem; +} +``` + +2. Impor CSS ke dalam komponen Anda + +```jsx +import "./my-class.css"; +``` + +3. Tambahkan kelas ke HTML Anda + +```html +
...
+``` + +Setara dalam Tailwind: + +1. Hanya menulis kelas dalam HTML Anda + +```html +
+ ... +
+``` + +Ketika digunakan bersama dengan Komponen React, Tailwind CSS sangat kuat untuk dengan cepat membangun UI. + +Tailwind CSS memiliki sistem desain bawaan yang indah, yang keluar dari kotak dengan palet warna yang dipilih dengan hati-hati, pola penentuan ukuran untuk gaya seperti lebar/tinggi dan padding/margin untuk desain seragam, serta breakpoint media untuk membuat tata letak responsif. Sistem desain ini dapat disesuaikan dan diperluas untuk membuat perangkat alat gaya yang sesuai dengan kebutuhan proyek Anda. + +
+ +
+ +Tru Narla yang lebih dikenal sebagai [mewtru](https://twitter.com/trunarla) memberikan presentasi luar biasa tentang [membangun sistem desain menggunakan Tailwind CSS](https://www.youtube.com/watch?v=T-Zv73yZ_QI). + +## Penggunaan + +Pastikan Anda telah menginstal plugin editor untuk Tailwind untuk meningkatkan pengalaman menulis Tailwind. + +### Ekstensi dan Plugin + +- [Ekstensi VSCode](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss) +- [Integrasi JetBrains](https://www.jetbrains.com/help/webstorm/tailwind-css.html#ws_css_tailwind_install) +- [Neovim LSP](https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md#tailwindcss) + +### Pemformatan + +Kelas-kelas Tailwind CSS dapat dengan mudah menjadi sedikit berantakan, jadi pemformat untuk kelas-kelas tersebut adalah suatu keharusan. [Plugin Prettier Tailwind CSS](https://github.com/tailwindlabs/prettier-plugin-tailwindcss) mengurutkan kelas-kelas dalam [urutan yang direkomendasikan](https://tailwindcss.com/blog/automatic-class-sorting-with-prettier#how-classes-are-sorted) sehingga kelas-kelas sesuai dengan bundel css yang dihasilkan. Saat memilih Tailwind dalam CLI, kami akan menginstal dan mengonfigurasi ini untuk Anda. + +### Penggunaan Kelas Secara Kondisional + +Menggunakan kelas secara kondisional dengan menggunakan operator ternary bisa menjadi sangat berantakan dan sulit dibaca. Paket-paket berikut membantu dalam mengorganisir kelas-kelas Anda saat menggunakan logika kondisional. + +- [clsx](https://github.com/lukeed/clsx) +- [classnames](https://github.com/JedWatson/classnames) + +## Sumber Daya Berguna + +| Sumber Daya | Tautan | +| -------------------------- | ---------------------------------------------------------- | +| Dokumentasi Tailwind | | +| Daftar Cepat Tailwind | | +| awesome-tailwindcss | | +| Komunitas Tailwind | | +| Server Discord Tailwind | | +| Kanal Youtube TailwindLabs | | +| Tailwind Playground | | diff --git a/www/src/pages/id/usage/trpc.md b/www/src/pages/id/usage/trpc.md new file mode 100644 index 0000000000..c5a1f09b3c --- /dev/null +++ b/www/src/pages/id/usage/trpc.md @@ -0,0 +1,386 @@ +--- +title: tRPC +description: Penggunaan tRPC +layout: ../../../layouts/docs.astro +lang: id +--- + +tRPC memungkinkan kita untuk menulis API yang aman tipe end-to-end tanpa kode generasi atau beban runtime. Ini menggunakan inferensi TypeScript yang luar biasa untuk menginfer definisi tipe router API Anda dan memungkinkan Anda untuk memanggil prosedur API Anda dari frontend dengan keamanan tipe penuh dan autokomplet. Saat menggunakan tRPC, frontend dan backend Anda terasa lebih dekat daripada sebelumnya, sehingga menghasilkan pengalaman pengembang yang luar biasa. + +
+
+

+ Saya membangun tRPC untuk memungkinkan orang bergerak lebih cepat dengan menghilangkan kebutuhan akan lapisan API tradisional, sambil tetap yakin bahwa aplikasi kita tidak akan rusak saat kita beriterasi dengan cepat. +

+
+ + Avatar of @alexdotjs +
+ Alex - pencipta tRPC + + @alexdotjs + +
+
+
+ +## Bagaimana Cara Menggunakan tRPC? + +
+ +
+ +Penyumbang tRPC [trashh_dev](https://twitter.com/trashh_dev) membuat [talk yang luar biasa di Next.js Conf](https://www.youtube.com/watch?v=2LYM8gf184U) tentang tRPC. Kami sangat merekomendasikan Anda menontonnya jika Anda belum melakukannya. + +Dengan tRPC, Anda menulis fungsi TypeScript di backend Anda, dan kemudian memanggilnya dari frontend Anda. Sebuah prosedur tRPC sederhana bisa terlihat seperti ini: + +```ts:server/api/routers/user.ts +const userRouter = createTRPCRouter({ + getById: publicProcedure.input(z.string()).query(({ ctx, input }) => { + return ctx.prisma.user.findFirst({ + where: { + id: input, + }, + }); + }), +}); +``` + +Ini adalah prosedur tRPC (setara dengan penanganan rute di backend tradisional) yang pertama-tama memvalidasi input menggunakan Zod (yang merupakan library validasi yang sama yang kami gunakan untuk [variabel lingkungan](./env-variables)) - dalam hal ini, memastikan bahwa input adalah string. Jika input bukan string, akan mengirimkan error informatif. + +Setelah input, kami menggabungkan fungsi resolver yang dapat berupa [query](https://trpc.io/docs/v10/react-queries), [mutation](https://trpc.io/docs/v10/react-mutations), atau [subscription](https://trpc.io/docs/v10/subscriptions). Dalam contoh kami, resolver memanggil basis data kami menggunakan klien [prisma](./prisma) kami dan mengembalikan pengguna yang `id`-nya cocok dengan yang kita lewati. + +Anda mendefinisikan prosedur Anda dalam `routers` yang mewakili kumpulan prosedur terkait dengan namespace bersama. Anda mungkin memiliki satu router untuk `pengguna`, satu untuk `pos`, dan lainnya untuk `pesan`. Router-router ini kemudian dapat digabungkan menjadi satu router `appRouter` yang terpusat: + +```ts:server/api/root.ts +const appRouter = createTRPCRouter({ + users: userRouter, + posts: postRouter, + messages: messageRouter, +}); + +export type AppRouter = typeof appRouter; +``` + +Perhatikan bahwa kami hanya perlu mengekspor definisi tipe router kami, yang berarti kami tidak pernah mengimpor kode server apa pun di client kami. + +Sekarang mari panggil prosedur di frontend kami. tRPC menyediakan wrapper untuk `@tanstack/react-query` yang memungkinkan Anda memanfaatkan semua kekuatan hooks yang mereka sediakan, tetapi dengan manfaat tambahan panggilan API Anda yang diketik dan diinferensikan. Kami dapat memanggil prosedur kami dari frontend kami seperti ini: + +```tsx:pages/users/[id].tsx +import { useRouter } from "next/router"; +import { api } from "../../utils/api"; + +const UserPage = () => { + const { query } = useRouter(); + const userQuery = api.users.getById.useQuery(query.id); + + return ( +
+

{userQuery.data?.name}

+
+ ); +}; +``` + +Anda akan segera melihat seberapa baik autokomplet dan keamanan tipe ini. Begitu Anda menulis `api.`, router Anda akan muncul dalam autokomplet, dan ketika Anda memilih router, prosedur-prosedurnya juga akan muncul. Anda juga akan mendapatkan error TypeScript jika input Anda tidak cocok dengan validator yang Anda tentukan di backend. + +## Menginfer Error + +Secara default, `create-t3-app` menyiapkan [formatter error](https://trpc.io/docs/error-formatting) yang memungkinkan Anda menginfer Error Zod jika Anda mendapatkan error validasi di backend. + +Contoh penggunaan: + +```tsx +function MyComponent() { + const { mutate, error } = api.post.create.useMutation(); + + return ( + { + e.preventDefault(); + const formData = new FormData(e.currentTarget); + mutate({ title: formData.get('title') }); + }}> + + {error?.data?.zodError?.field + +Errors.title && ( + {/** `mutate` mengembalikan error di `title` */} + + {error.data.zodError.fieldErrors.title} + + )} + + ... + + ); +} +``` + +## Berkas + +tRPC memerlukan cukup banyak boilerplate yang disiapkan oleh `create-t3-app`. Mari kita bahas berkas-berkas yang dihasilkan: + +### 📄 `pages/api/trpc/[trpc].ts` + +Ini adalah titik masuk untuk API Anda dan mengekspos router tRPC. Biasanya, Anda tidak akan banyak menyentuh file ini, tetapi jika Anda perlu, misalnya, mengaktifkan middleware CORS atau sejenisnya, berguna untuk mengetahui bahwa `createNextApiHandler` yang diekspor adalah [penangan API Next.js](https://nextjs.org/docs/api-routes/introduction) yang mengambil objek [request](https://developer.mozilla.org/en-US/docs/Web/API/Request) dan [response](https://developer.mozilla.org/en-US/docs/Web/API/Response). Ini berarti Anda dapat membungkus `createNextApiHandler` dalam middleware apa pun yang Anda inginkan. Lihat di bawah untuk [contoh potongan](#enabling-cors) menambahkan CORS. + +### 📄 `server/api/trpc.ts` + +File ini dibagi menjadi dua bagian, pembuatan konteks dan inisialisasi tRPC: + +1. Kami mendefinisikan konteks yang diberikan ke prosedur tRPC Anda. Konteks adalah data yang akan diakses oleh semua prosedur tRPC Anda, dan merupakan tempat yang baik untuk meletakkan hal-hal seperti koneksi database, informasi otentikasi, dll. Di create-t3-app, kami menggunakan dua fungsi, untuk memungkinkan penggunaan subset konteks ketika kami tidak memiliki akses ke objek permintaan. + +- `createInnerTRPCContext`: Ini adalah tempat Anda mendefinisikan konteks yang tidak bergantung pada permintaan, misalnya, koneksi database Anda. Anda dapat menggunakan fungsi ini untuk [pengujian integrasi](#sample-integration-test) atau [ssg-helpers](https://trpc.io/docs/v10/ssg-helpers) di mana Anda tidak memiliki objek permintaan. + +- `createTRPCContext`: Inilah tempat Anda mendefinisikan konteks yang bergantung pada permintaan, misalnya, sesi pengguna. Anda meminta sesi menggunakan objek `opts.req`, dan kemudian meneruskan sesi ke fungsi `createInnerTRPCContext` untuk membuat konteks akhir. + +2. Kami menginisialisasi tRPC dan mendefinisikan [prosedur](https://trpc.io/docs/v10/procedures) yang dapat digunakan kembali dan [middlewares](https://trpc.io/docs/v10/middlewares). Menurut konvensi, Anda sebaiknya tidak mengekspor seluruh objek `t`, tetapi sebaliknya, membuat prosedur dan middlewares yang dapat digunakan kembali dan mengekspornya. + +Anda akan melihat kami menggunakan `superjson` sebagai [data transformer](https://trpc.io/docs/v10/data-transformers). Ini membuatnya sehingga tipe data Anda tetap ada saat mencapai client, sehingga jika Anda, misalnya, mengirimkan objek `Date`, client akan mengembalikan `Date` dan bukan string seperti yang terjadi pada sebagian besar API. + +### 📄 `server/api/routers/*.ts` + +Di sinilah Anda mendefinisikan rute dan prosedur API Anda. Menurut konvensi, Anda [membuat router terpisah](https://trpc.io/docs/v10/router) untuk prosedur terkait. + +### 📄 `server/api/root.ts` + +Di sini kita [menggabungkan](https://trpc.io/docs/v10/merging-routers) semua sub-router yang didefinisikan di `routers/**` menjadi satu router aplikasi. + +### 📄 `utils/api.ts` + +Ini adalah titik masuk frontend untuk tRPC. Di sinilah Anda akan mengimpor **definisi tipe** router dan membuat klien tRPC Anda bersama dengan hook react-query. Karena kami mengaktifkan `superjson` sebagai transformer data kami di backend, kami perlu mengaktifkannya juga di frontend. Ini karena data yang diserialkan dari backend akan dideserialkan di frontend. + +Anda akan mendefinisikan [link tRPC](https://trpc.io/docs/v10/links) Anda di sini, yang menentukan aliran permintaan dari client ke server. Kami menggunakan "default" [`httpBatchLink`](https://trpc.io/docs/v10/links/httpBatchLink) yang mengaktifkan [request batching](https://cloud.google.com/compute/docs/api/how-tos/batch), serta [`loggerLink`](https://trpc.io/docs/v10/links/loggerLink) yang menghasilkan log permintaan yang berguna selama pengembangan. + +Terakhir, kami mengekspor [tipe pembantu](https://trpc.io/docs/v10/infer-types#additional-dx-helper-type) yang dapat Anda gunakan untuk menginfer tipe Anda di frontend. + +
+ +
+ +Kontributor Create T3 App [Christopher Ehrlich](https://twitter.com/ccccjjjjeeee) membuat [video tentang aliran data di tRPC](https://www.youtube.com/watch?v=x4mu-jOiA0Q). Video ini direkomendasikan jika Anda telah menggunakan tRPC tetapi masih merasa agak kurang jelas tentang bagaimana itu bekerja. + +## Bagaimana Cara Memanggil API Saya Secara Eksternal? + +Dengan API reguler, Anda dapat memanggil endpoint Anda menggunakan klien HTTP apa pun seperti `curl`, `Postman`, `fetch`, atau langsung dari browser Anda. Dengan tRPC, ini agak berbeda. Jika Anda ingin memanggil prosedur Anda tanpa klien tRPC, ada dua cara yang direkomendasikan untuk melakukannya: + +### Mengekspos Satu Prosedur Secara Eksternal + +Jika Anda ingin mengekspos satu prosedur secara eksternal, Anda mencari [panggilan sisi server](https://trpc.io/docs/v10/server-side-calls). Ini akan memungkinkan Anda membuat endpoint API Next.js biasa, tetapi dapat menggunakan bagian resolver dari prosedur tRPC Anda. + +```ts:pages/api/users/[id].ts +import { type NextApiRequest, type NextApiResponse } from "next"; +import { appRouter } from "../../../server/api/root"; +import { createTRPCContext } from "../../../server/api/trpc"; + +const userByIdHandler = async (req: NextApiRequest, res: NextApiResponse) => { + // Buat konteks dan pemanggil + const ctx = await createTRPCContext({ req, res }); + const caller = appRouter.createCaller(ctx); + try { + const { id } = req.query; + const user = await caller.user.getById(id); + res.status(200).json(user); + } catch (cause) { + if (cause instanceof TRPCError) { + // Terjadi kesalahan dari tRPC + const httpCode = getHTTPStatusCodeFromError(cause); + return res.status(httpCode).json(cause); + } + // Terjadi kesalahan lainnya + console.error(cause); + res.status(500).json({ message: "Kesalahan server internal" }); + } +}; + +export default userByIdHandler; +``` + +### Mengekspos Setiap Prosedur Sebagai Endpoint REST + +Jika Anda ingin mengekspos setiap prosedur secara eksternal, coba plugin yang dibuat oleh komunitas bernama [trpc-openapi](https://github.com/jlalmes/trpc-openapi/tree/master). Dengan menyediakan beberapa meta-data tambahan untuk prosedur-prosedur Anda, Anda dapat menghasilkan API REST yang sesuai dengan OpenAPI dari router tRPC Anda. + +### Ini Hanya Permintaan HTTP + +tRPC berkomunikasi melalui HTTP, jadi memang mungkin untuk memanggil prosedur tRPC Anda menggunakan permintaan HTTP "biasa". Namun, sintaksnya bisa jadi cukup rumit karena [protokol RPC](https://trpc.io/docs/v10/rpc) yang digunakan oleh tRPC. Jika Anda penasaran, Anda bisa melihat bagaimana permintaan dan respons tRPC terlihat di tab jaringan browser Anda, tetapi kami menyarankan untuk melakukannya hanya sebagai latihan edukatif dan tetap menggunakan salah satu solusi yang dijelaskan di atas. + +## Perbandingan dengan Endpoint API Next.js + +Mari kita bandingkan sebuah endpoint API Next.js dengan prosedur tRPC. Katakanlah kita ingin mengambil objek pengguna dari database dan mengembalikannya ke frontend. Kita bisa menulis endpoint API Next.js seperti ini: + +```ts:pages/api/users/[id].ts +import { type NextApiRequest, type NextApiResponse } from "next"; +import { prisma } from "../../../server/db"; + +const userByIdHandler = async (req: NextApiRequest, res: NextApiResponse) => { + if (req.method !== "GET") { + return res.status(405).end(); + } + + const { id } = req.query; + + if (!id || typeof id !== "string") { + return res.status(400).json({ error: "ID tidak valid" }); + } + + const examples = await prisma.example.findFirst({ + where: { + id, + }, + }); + + res.status(200).json(examples); +}; + +export default userByIdHandler; +``` + +```ts:pages/users/[id].tsx +import { useState, useEffect } from "react"; +import { useRouter } from "next/router"; + +const UserPage = () => { + const router = useRouter(); + const { id } = router.query; + + const [user, setUser] = useState(null); + useEffect(() => { + fetch(`/api/user/${id}`) + .then((res) => res.json()) + .then((data) => setUser(data)); + }, [id]); +}; +``` + +Bandingkan dengan contoh tRPC di atas, Anda dapat melihat beberapa keunggulan tRPC: + +- Daripada menentukan URL untuk setiap rute, yang bisa menjadi merepotkan untuk didebug jika ada perubahan, seluruh router Anda adalah objek dengan fitur autocomplete. +- Anda tidak perlu memvalidasi metode HTTP yang digunakan. +- Anda tidak perlu memvalidasi bahwa permintaan query atau body mengandung data yang benar dalam prosedur, karena Zod akan menangani ini. +- Daripada membuat respons, Anda dapat melempar kesalahan dan mengembalikan nilai atau objek seperti yang Anda lakukan dalam fungsi TypeScript lainnya. +- Memanggil prosedur di frontend memberikan autocomplete dan keamanan tipe. + +## Potongan Kode Berguna + +Berikut beberapa potongan kode yang mungkin berguna. + +### Mengaktifkan CORS + +Jika Anda perlu mengonsumsi API Anda dari domain yang berbeda, misalnya dalam sebuah monorepo yang mencakup aplikasi React Native, Anda mungkin perlu mengaktifkan CORS: + +```ts:pages/api/trpc/[trpc].ts +import { type NextApiRequest, type NextApiResponse } from "next"; +import { createNextApiHandler } from "@trpc/server/adapters/next"; +import { appRouter } from "~/server/api/root"; +import { createTRPCContext } from "~/server/api/trpc"; +import cors from "nextjs-cors"; + +const handler = async (req: NextApiRequest, res: NextApiResponse) => { + // Aktifkan CORS + await cors(req, res); + + // Buat dan panggil handler tRPC + return createNextApiHandler({ + router: appRouter, + createContext: createTRPCContext, + })(req, res); +}; + +export default handler; +``` + +### Pembaruan Optimis + +Pembaruan optimis adalah ketika kita memperbarui UI sebelum panggilan API selesai. Ini memberikan pengalaman yang lebih baik bagi pengguna karena mereka tidak perlu menunggu panggilan API selesai sebelum UI mencerminkan hasil dari tindakan mereka. Namun, aplikasi yang sangat mengutamakan kebenaran data sebaiknya menghindari pembaruan optimis karena ini bukan representasi "benar" dari status backend. Anda dapat membaca lebih lanjut di [dokumentasi React Query](https://tanstack.com/query/v4/docs/guides/optimistic-updates). + +```tsx +const MyComponent = () => { + const listPostQuery = api.post.list.useQuery(); + + const utils = api.useContext(); + const postCreate = api.post.create.useMutation({ + async onMutate(newPost) { + // Batalkan fetch yang sedang berlangsung (sehingga mereka + + tidak mengganti pembaruan optimis kita) + await utils.post.list.cancel(); + + // Dapatkan data dari queryCache + const prevData = utils.post.list.getData(); + + // Perbarui data secara optimis dengan pos baru kita + utils.post.list.setData(undefined, (old) => [...old, newPost]); + + // Kembalikan data sebelumnya sehingga kita dapat mengembalikannya jika terjadi masalah + return { prevData }; + }, + onError(err, newPost, ctx) { + // Jika mutasi gagal, gunakan nilai konteks dari onMutate + utils.post.list.setData(undefined, ctx.prevData); + }, + onSettled() { + // Sinkronkan dengan server setelah mutasi selesai + utils.post.list.invalidate(); + }, + }); +}; +``` + +### Contoh Pengujian Integrasi + +Berikut contoh pengujian integrasi yang menggunakan [Vitest](https://vitest.dev) untuk memeriksa apakah router tRPC Anda berfungsi seperti yang diharapkan, parser input menyimpulkan tipe yang benar, dan data yang dikembalikan cocok dengan hasil yang diharapkan. + +```ts +import { type inferProcedureInput } from "@trpc/server"; +import { expect, test } from "vitest"; + +import { appRouter, type AppRouter } from "~/server/api/root"; +import { createInnerTRPCContext } from "~/server/api/trpc"; + +test("contoh router", async () => { + const ctx = await createInnerTRPCContext({ session: null }); + const caller = appRouter.createCaller(ctx); + + type Input = inferProcedureInput; + const input: Input = { + teks: "tes", + }; + + const contoh = await caller.contoh.halo(input); + + expect(contoh).toMatchObject({ sapaan: "Halo tes" }); +}); +``` + +Jika prosedur Anda dilindungi, Anda dapat melewatkan objek `session` yang dimock saat Anda membuat konteks: + +```ts +test("contoh router yang dilindungi", async () => { + const ctx = await createInnerTRPCContext({ + session: { + user: { id: "123", name: "John Doe" }, + expires: "1", + }, + }); + const caller = appRouter.createCaller(ctx); + + // ... +}); +``` + +## Sumber Daya Berguna + +| Sumber Daya | Tautan | +| ----------------------- | --------------------------------------------------------- | +| Dokumentasi tRPC | | +| Banyak Contoh tRPC | | +| Dokumentasi React Query | | diff --git a/www/src/pages/id/usage/typescript.md b/www/src/pages/id/usage/typescript.md new file mode 100644 index 0000000000..6e82eacaab --- /dev/null +++ b/www/src/pages/id/usage/typescript.md @@ -0,0 +1,67 @@ +--- +title: TypeScript +description: Penggunaan TypeScript +layout: ../../../layouts/docs.astro +lang: id +--- + +
+
+

+ Bangun jaringan keamanan, bukan pagar pelindung +

+
+ + Avatar of @t3dotgg +
+ Theo - pencipta T3 Stack + + @t3dotgg + +
+
+
+ +Baik Anda seorang pengembang baru atau berpengalaman, kami berpikir bahwa TypeScript adalah suatu keharusan. Ini mungkin tampak menakutkan pada awalnya, tetapi seperti banyak alat lainnya, ini adalah sesuatu yang banyak orang tidak pernah menyesalinya setelah mulai menggunakannya. + +Ini memberikan umpan balik langsung saat Anda menulis kode Anda dengan mendefinisikan tipe data yang diharapkan, dan entah memberikan penyelesaian otomatis yang berguna di editor kode Anda, atau berteriak pada Anda dengan garis-garis merah bergelombang jika Anda mencoba mengakses properti yang tidak ada atau mencoba meneruskan nilai dengan jenis yang salah, yang sebaliknya akan membuat Anda harus melakukan debugging lebih lanjut. + +Mungkin ini adalah alat yang memberikan produktivitas terbanyak kepada para pengembang; memberikan dokumentasi kode yang Anda tulis atau konsumsi langsung di editor Anda, dan memberikan umpan balik instan saat Anda melakukan kesalahan adalah benar-benar tak ternilai. + +## Inferensi Tipe + +Meskipun banyak pengembang TypeScript baru khawatir tentang _menulis_ TypeScript, banyak manfaatnya sebenarnya tidak memerlukan Anda untuk mengubah kode Anda sama sekali, terutama inferensi. Inferensi berarti jika sesuatu memiliki tipe, tipe itu akan mengikuti selama aliran aplikasi tanpa perlu dideklarasikan ulang di tempat lain. Ini berarti bahwa, sebagai contoh, begitu Anda telah mendefinisikan tipe argumen yang diterima oleh suatu fungsi, sisa fungsi tersebut biasanya akan aman dalam hal tipe tanpa memerlukan kode khusus TypeScript lebih lanjut. Pengembang perpustakaan banyak bekerja keras untuk mempertahankan tipe-tipe perpustakaan mereka, yang berarti bahwa kami sebagai pengembang aplikasi dapat mengambil manfaat dari inferensi dan dokumentasi bawaan dalam editor kode Anda yang diberikan oleh tipe-tipe ini. + +
+ +
+ +Lihat video Theo tentang [Anda mungkin salah menggunakan TypeScript](https://www.youtube.com/watch?v=RmGHnYUqQ4k). + +## Penggunaan Kuat dari Inferensi Tipe + +### Zod + +[Zod](https://github.com/colinhacks/zod) adalah perpustakaan validasi skema yang dibangun di atas TypeScript. Tulis skema yang mewakili sumber kebenaran tunggal untuk data Anda, dan Zod akan memastikan bahwa data Anda valid di seluruh aplikasi Anda, bahkan melintasi batas jaringan dan API eksternal. + +### Tanstack Query + +[Tanstack Query](https://tanstack.com/query/v4/) memberikan Anda kueri dan mutasi yang deklaratif, selalu terkini, dan dikelola otomatis yang secara langsung meningkatkan pengalaman pengembang dan pengguna Anda. + +## Sumber Daya Berguna + +| Sumber Daya | Tautan | +| ---------------------------------------------------------------- | ------------------------------------------------------------------- | +| Panduan TypeScript | | +| Tutorial TypeScript untuk Pemula | | +| Tantangan Tipe | | +| Saluran Youtube "Rodney Mullen" (Matt Pocock) tentang TypeScript | | diff --git a/www/src/pages/id/why.md b/www/src/pages/id/why.md new file mode 100644 index 0000000000..1702bdc765 --- /dev/null +++ b/www/src/pages/id/why.md @@ -0,0 +1,50 @@ +--- +title: Mengapa CT3A? +description: Mengapa Anda harus memilih Create T3 App untuk proyek selanjutnya +layout: ../../layouts/docs.astro +lang: id +--- + +Kami memulai Create T3 App karena [Theo](https://twitter.com/t3dotgg) menolak untuk membuat template dari teknologi favoritnya. Terinspirasi oleh create-next-app, [CLI Astro](https://astro.build) dan cinta umum untuk typesafety, tim Create T3 App bekerja keras untuk membangun titik awal yang terbaik untuk proyek T3 Stack baru. + +Jika Anda tertarik menggunakan Next.js dengan cara yang typesafe, ini adalah tempat untuk memulai. Jika Anda penasaran tentang pilihan teknologi spesifik yang kami buat, silakan baca lebih lanjut :) + +## Mengapa TypeScript? + +JavaScript itu sulit. Mengapa menambah lebih banyak aturan? + +Kami percaya bahwa pengalaman yang diberikan oleh TypeScript akan membantu Anda menjadi pengembang yang lebih baik. Ini memberikan umpan balik langsung saat Anda menulis kode dengan mendefinisikan tipe data yang diharapkan, dan memberikan autocomplete yang membantu di editor Anda atau memberi tahu Anda dengan garis bergelombang merah jika Anda mencoba mengakses properti yang tidak ada atau mencoba melewati nilai dengan tipe yang salah, yang sebaliknya Anda harus debug lebih lanjut. Apakah Anda baru dalam pengembangan web atau sudah berpengalaman, "keketatan" dari TypeScript akan memberikan pengalaman yang kurang frustasi, lebih konsisten daripada JS vanila. + +Typesafety membuat Anda lebih cepat. Jika Anda belum yakin, Anda [mungkin menggunakan TypeScript dengan cara yang salah...](https://www.youtube.com/watch?v=RmGHnYUqQ4k) + +## Mengapa Next.js? + +Kami suka React. Ini telah membuat pengembangan UI dapat diakses dengan cara yang tidak pernah kami bayangkan sebelumnya. Ini juga bisa membawa pengembang ke beberapa jalan yang berat. + +Next.js menawarkan pendekatan yang sedikit beropini, sangat dioptimalkan untuk membuat aplikasi menggunakan React. Mulai dari routing hingga definisi API hingga rendering gambar, kami percaya Next.js untuk membimbing pengembang menuju keputusan yang baik. + +## Mengapa tRPC/Prisma/Tailwind/dll? + +Meskipun kami percaya dalam menjaga segala sesuatu sesederhana mungkin, kami menemukan potongan-potongan ini digunakan di setiap proyek "aplikasi" seperti yang kami bangun. `create-t3-app` melakukan pekerjaan yang sangat baik membiarkan Anda mengadopsi potongan-potongan yang Anda butuhkan. + +### tRPC + +tRPC memberikan janji GraphQL tentang pengembangan klien yang mulus terhadap server yang typesafe tanpa semua boilerplate. Ini adalah penyalahgunaan TypeScript yang cerdas yang memberikan pengalaman dev yang luar biasa. + +### Prisma + +Prisma adalah untuk SQL, TypeScript adalah untuk JS. Ini menciptakan pengalaman pengembang yang belum pernah ada sebelumnya. Dengan menghasilkan tipe dari skema yang didefinisikan oleh pengguna yang kompatibel dengan [beberapa basis data](https://www.prisma.io/docs/concepts/database-connectors), Prisma menjamin typesafety dari ujung ke ujung dari basis data Anda hingga aplikasi Anda. + +Prisma menyediakan seluruh [rangkaian alat](https://www.prisma.io/docs/concepts/overview/should-you-use-prisma#-you-want-a-tool-that-holistically-covers-your-database-workflows) yang membuat interaksi sehari-hari dengan basis data Anda lebih mudah. Terutama, Klien Prisma bertanggung jawab untuk query dan membuat SQL begitu mudah sehingga Anda hampir tidak menyadari Anda menggunakannya, dan Prisma Studio adalah GUI yang nyaman untuk basis data Anda yang memungkinkan Anda membaca dan memanipulasi data Anda dengan cepat tanpa harus menulis kode. + +### Tailwind CSS + +Tailwind terasa seperti "CSS mode zen". + +Dengan menyediakan blok bangunan berupa warna default yang baik, spasi, dan primitif lainnya, Tailwind memudahkan pembuatan aplikasi yang tampak baik. Dan tidak seperti pustaka komponen, ia tidak menghambat Anda ketika Anda ingin membawa aplikasi Anda ke level berikutnya dan menciptakan sesuatu yang indah dan unik. + +Selain itu, dengan pendekatannya yang seperti inline, Tailwind mendorong Anda untuk gaya tanpa khawatir tentang penamaan kelas, mengatur file, atau masalah lain yang tidak langsung terkait dengan masalah yang Anda coba selesaikan. + +### NextAuth.js + +Ketika Anda ingin sistem autentikasi di aplikasi NextJS Anda, NextAuth.js adalah solusi yang sangat baik untuk membawa kompleksitas keamanan tanpa repot harus membangunnya sendiri. Ini datang dengan daftar penyedia yang luas untuk segera menambahkan autentikasi OAuth dan menyediakan adaptor untuk banyak basis data dan ORM.