From 274cce603b3b036254e52baf022be8d5985b7612 Mon Sep 17 00:00:00 2001 From: Imamuzzaki Abu Salam Date: Mon, 30 Oct 2023 09:01:35 +0700 Subject: [PATCH 01/13] docs: copy from en --- www/src/pages/id/deployment/docker.md | 214 +++++++++++++ www/src/pages/id/deployment/index.astro | 24 ++ www/src/pages/id/deployment/netlify.mdx | 93 ++++++ www/src/pages/id/deployment/vercel.md | 63 ++++ www/src/pages/id/examples.mdx | 22 ++ www/src/pages/id/faq.mdx | 76 +++++ www/src/pages/id/folder-structure.mdx | 212 +++++++++++++ www/src/pages/id/installation.mdx | 72 +++++ www/src/pages/id/other-recs.md | 163 ++++++++++ www/src/pages/id/t3-collection.mdx | 29 ++ www/src/pages/id/usage/drizzle.mdx | 14 + www/src/pages/id/usage/env-variables.mdx | 149 +++++++++ www/src/pages/id/usage/first-steps.md | 50 +++ www/src/pages/id/usage/index.astro | 24 ++ www/src/pages/id/usage/next-auth.mdx | 228 ++++++++++++++ www/src/pages/id/usage/next-js.md | 37 +++ www/src/pages/id/usage/prisma.md | 78 +++++ www/src/pages/id/usage/tailwind.md | 96 ++++++ www/src/pages/id/usage/trpc.md | 382 +++++++++++++++++++++++ www/src/pages/id/usage/typescript.md | 67 ++++ www/src/pages/id/why.md | 50 +++ 21 files changed, 2143 insertions(+) create mode 100644 www/src/pages/id/deployment/docker.md create mode 100644 www/src/pages/id/deployment/index.astro create mode 100644 www/src/pages/id/deployment/netlify.mdx create mode 100644 www/src/pages/id/deployment/vercel.md create mode 100644 www/src/pages/id/examples.mdx create mode 100644 www/src/pages/id/faq.mdx create mode 100644 www/src/pages/id/folder-structure.mdx create mode 100644 www/src/pages/id/installation.mdx create mode 100644 www/src/pages/id/other-recs.md create mode 100644 www/src/pages/id/t3-collection.mdx create mode 100644 www/src/pages/id/usage/drizzle.mdx create mode 100644 www/src/pages/id/usage/env-variables.mdx create mode 100644 www/src/pages/id/usage/first-steps.md create mode 100644 www/src/pages/id/usage/index.astro create mode 100644 www/src/pages/id/usage/next-auth.mdx create mode 100644 www/src/pages/id/usage/next-js.md create mode 100644 www/src/pages/id/usage/prisma.md create mode 100644 www/src/pages/id/usage/tailwind.md create mode 100644 www/src/pages/id/usage/trpc.md create mode 100644 www/src/pages/id/usage/typescript.md create mode 100644 www/src/pages/id/why.md diff --git a/www/src/pages/id/deployment/docker.md b/www/src/pages/id/deployment/docker.md new file mode 100644 index 0000000000..f9941e0e2a --- /dev/null +++ b/www/src/pages/id/deployment/docker.md @@ -0,0 +1,214 @@ +--- +title: Docker +description: Deployment with Docker +layout: ../../../layouts/docs.astro +lang: en +--- + +You can containerize this stack and deploy it as a single container using Docker, or as a part of a group of containers using docker-compose. See [`ajcwebdev/ct3a-docker`](https://github.com/ajcwebdev/ct3a-docker) for an example repo based on this doc. + +## Docker Project Configuration + +Please note that Next.js requires a different process for build time (available in the frontend, prefixed by `NEXT_PUBLIC`) and runtime environment, server-side only, variables. In this demo we are using two variables, pay attention to their positions in the `Dockerfile`, command-line arguments, and `docker-compose.yml`: + +- `DATABASE_URL` (used by the server) +- `NEXT_PUBLIC_CLIENTVAR` (used by the client) + +### 1. Next Configuration + +In your [`next.config.mjs`](https://github.com/t3-oss/create-t3-app/blob/main/cli/template/base/next.config.mjs), add the `standalone` output-option configuration to [reduce image size by automatically leveraging output traces](https://nextjs.org/docs/advanced-features/output-file-tracing): + +```diff +export default defineNextConfig({ + reactStrictMode: true, + swcMinify: true, ++ output: "standalone", +}); +``` + +### 2. Create dockerignore file + +
+ + Click here and include contents in .dockerignore: + +
+ +``` +.env +Dockerfile +.dockerignore +node_modules +npm-debug.log +README.md +.next +.git +``` + +
+ +
+ +### 3. Create Dockerfile + +> Since we're not pulling the server environment variables into our container, the [environment schema validation](/en/usage/env-variables) will fail. To prevent this, we have to add a `SKIP_ENV_VALIDATION=1` flag to the build command so that the env-schemas aren't validated at build time. + +
+ + Click here and include contents in 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"] + +``` + +> **_Notes_** +> +> - _Emulation of `--platform=linux/amd64` may not be necessary after moving to Node 18._ +> - _See [`node:alpine`](https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine) to understand why `libc6-compat` might be needed._ +> - _Using Alpine 3.17 based images [can cause issues with Prisma](https://github.com/t3-oss/create-t3-app/issues/975). Setting `engineType = "binary"` solves the issue in Alpine 3.17, [but has an associated performance cost](https://www.prisma.io/docs/concepts/components/prisma-engines/query-engine#the-query-engine-at-runtime)._ +> - _Next.js collects [anonymous telemetry data about general usage](https://nextjs.org/telemetry). Uncomment the first instance of `ENV NEXT_TELEMETRY_DISABLED 1` to disable telemetry during the build. Uncomment the second instance to disable telemetry during runtime._ + +
+
+ +## Build and Run Image Locally + +Build and run this image locally with the following commands: + +```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 +``` + +Open [localhost:3000](http://localhost:3000/) to see your running application. + +## Docker Compose + +You can also use Docker Compose to build the image and run the container. + +
+ + Follow steps 1-4 above, click here, and include contents in 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 +``` + +Run this using the `docker compose up` command: + +```bash +docker compose up +``` + +Open [localhost:3000](http://localhost:3000/) to see your running application. + +
+
+ +## Deploy to Railway + +You can use a PaaS such as [Railway's](https://railway.app) automated [Dockerfile deployments](https://docs.railway.app/deploy/dockerfiles) to deploy your app. If you have the [Railway CLI installed](https://docs.railway.app/develop/cli#install) you can deploy your app with the following commands: + +```bash +railway login +railway init +railway link +railway up +railway open +``` + +Go to "Variables" and include your `DATABASE_URL`. Then go to "Settings" and select "Generate Domain." To view a running example on Railway, visit [ct3a-docker.up.railway.app](https://ct3a-docker.up.railway.app/). + +## Useful Resources + +| Resource | Link | +| ------------------------------------ | -------------------------------------------------------------------- | +| Dockerfile reference | https://docs.docker.com/engine/reference/builder/ | +| Compose file version 3 reference | https://docs.docker.com/compose/compose-file/compose-file-v3/ | +| Docker CLI reference | https://docs.docker.com/engine/reference/commandline/docker/ | +| Docker Compose CLI reference | https://docs.docker.com/compose/reference/ | +| Next.js Deployment with Docker Image | https://nextjs.org/docs/deployment#docker-image | +| Next.js in Docker | https://benmarte.com/blog/nextjs-in-docker/ | +| Next.js with Docker Example | https://github.com/vercel/next.js/tree/canary/examples/with-docker | +| Create Docker Image of a Next.js app | https://blog.tericcabrel.com/create-docker-image-nextjs-application/ | diff --git a/www/src/pages/id/deployment/index.astro b/www/src/pages/id/deployment/index.astro new file mode 100644 index 0000000000..22aec56d1d --- /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: "Learn how to deploy your T3 app to production.", +}; + +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..a2fddd8c63 --- /dev/null +++ b/www/src/pages/id/deployment/netlify.mdx @@ -0,0 +1,93 @@ +--- +title: Netlify +description: Deploying to Netlify +layout: ../../../layouts/docs.astro +lang: en +isMdx: true +--- + +import Callout from "../../../components/docs/callout.tsx"; + +Netlify is an alternative deployment provider in a similar vein to Vercel. See [`ajcwebdev/ct3a-netlify`](https://github.com/ajcwebdev/ct3a-netlify) for an example repo based on this doc. + +## Why Host on Netlify + +Conventional wisdom says Vercel has superior Next.js support because Vercel develops Next.js. They have a vested interest in ensuring the platform is tuned for optimal performance and DX with Next.js. For the majority of use cases this will be true and it won't make sense to deviate from the standard path. + +There's also a common sentiment that many Next.js features are only supported on Vercel. While it's true that new Next.js features will be tested and supported on Vercel at the time of release by default, it's also the case that other providers like Netlify will [quickly implement and release support](https://www.netlify.com/blog/deploy-nextjs-13/) for [stable Next.js features](https://docs.netlify.com/integrations/frameworks/next-js/overview/). + +There are relative pros and cons for all deployment providers since no single host can have the best support for all use cases. For example, Netlify built their own [custom Next.js runtime](https://github.com/netlify/next-runtime) for Netlify's Edge Functions (which run on Deno Deploy) and [maintain unique middleware to access and modify HTTP responses](https://github.com/netlify/next-runtime#nextjs-middleware-on-netlify). + + + To track the status of non-stable Next 13 features see [Using the Next 13 + `app` directory on + Netlify](https://github.com/netlify/next-runtime/discussions/1724). + + +## Project Configuration + +There are numerous ways to configure your build instructions including directly through the Netlify CLI or Netlify dashboard. While not required, it is advisable to create and include a [`netlify.toml`](https://docs.netlify.com/configure-builds/file-based-configuration/) file. This ensures forked and cloned versions of the project will be easier to reproducibly deploy. + +```toml +[build] + command = "next build" + publish = ".next" +``` + +## Using the Netlify Dashboard + +1. Push your code to a GitHub repository and sign up for [Netlify](https://app.netlify.com/signup). After you've created an account, click on **Add new site** and then **Import an existing project**. + +![New project on Netlify](/images/netlify-01-new-project.webp) + +2. Connect your Git provider. + +![Import repository](/images/netlify-02-connect-to-git-provider.webp) + +3. Select your project's repository. + +![Select your project's repository](/images/netlify-03-pick-a-repository-from-github.webp) + +4. Netlify will detect if you have a `netlify.toml` file and automatically configure your build command and publish directory. + +![Nextjs build settings](/images/netlify-04-configure-build-settings.webp) + +5. Click **Show advanced** and then **New variable** to add your environment variables. + +![Add environment variables](/images/netlify-05-env-vars.webp) + +6. Click **Deploy site**, wait for the build to complete, and view your new site. + +## Using the Netlify CLI + +To deploy from the command line you must first push your project to a GitHub repo and [install the Netlify CLI](https://docs.netlify.com/cli/get-started/). You can install `netlify-cli` as a project dependency or install it globally on your machine with the following command: + +```bash +npm i -g netlify-cli +``` + +To test your project locally, run the [`ntl dev`](https://docs.netlify.com/cli/get-started/#run-a-local-development-environment) command and open [`localhost:8888`](http://localhost:8888/) to view your locally running Netlify app: + +```bash +ntl dev +``` + +Run the [`ntl init`](https://docs.netlify.com/cli/get-started/#continuous-deployment) command to configure your project: + +```bash +ntl init +``` + +Import your project's environment variables from your `.env` file with [`ntl env:import`](https://cli.netlify.com/commands/env#envimport): + +```bash +ntl env:import .env +``` + +Deploy your project with [`ntl deploy`](https://docs.netlify.com/cli/get-started/#manual-deploys). You'll need to pass the `--build` flag to run the build command before deployment and the `--prod` flag to deploy to your site's main URL: + +```bash +ntl deploy --prod --build +``` + +To view a running example on Netlify, visit [ct3a.netlify.app](https://ct3a.netlify.app/). diff --git a/www/src/pages/id/deployment/vercel.md b/www/src/pages/id/deployment/vercel.md new file mode 100644 index 0000000000..40609cf229 --- /dev/null +++ b/www/src/pages/id/deployment/vercel.md @@ -0,0 +1,63 @@ +--- +title: Vercel +description: Deploying to Vercel +layout: ../../../layouts/docs.astro +lang: en +--- + +We recommend deploying your app to [Vercel](https://vercel.com/?utm_source=t3-oss&utm_campaign=oss). It makes it super easy to deploy Next.js apps. + +## Project Configuration + +Vercel will likely configure your build command and publish the directory automatically. However, you can also specify this information along with other configurations by creating a file called [`vercel.json`](https://vercel.com/docs/project-configuration) and including the following commands. **This is not required for most projects.** + +```json +{ + "buildCommand": "npm run build", + "outputDirectory": "dist", + "devCommand": "npm run dev", + "installCommand": "npm install" +} +``` + +## Using the Vercel Dashboard + +1. After pushing your code to a GitHub repository, sign up for [Vercel](https://vercel.com/?utm_source=t3-oss&utm_campaign=oss) with GitHub and click on **Add New Project**. + +![New project on Vercel](/images/vercel-new-project.webp) + +2. Import the GitHub repository with your project. + +![Import repository](/images/vercel-import-project.webp) + +3. Add your environment variables. + +![Add environment variables](/images/vercel-env-vars.webp) + +4. Click **Deploy**. Now whenever you push a change to your repository, Vercel will automatically redeploy your app! + +## Using the Vercel CLI + +To deploy from the command line you must first [install the Vercel CLI globally](https://vercel.com/docs/cli#installing-vercel-cli). + +```bash +npm i -g vercel +``` + +Run the [`vercel`](https://vercel.com/docs/cli/deploying-from-cli) command to deploy your project. + +```bash +vercel +``` + +Include `--env DATABASE_URL=YOUR_DATABASE_URL_HERE` for environment variables like the database connection string. Use `--yes` if you want to skip the deployment questions and give the default answer for each. + +```bash +vercel --env DATABASE_URL=YOUR_DATABASE_URL_HERE --yes +``` + +After the first deployment this command will deploy to a preview branch. You will need to include `--prod` to push changes directly to the live site for future deployments. + +```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..bc7e45fb62 --- /dev/null +++ b/www/src/pages/id/examples.mdx @@ -0,0 +1,22 @@ +--- +title: Examples +description: Examples of different live apps +layout: ../../layouts/docs.astro +lang: en +isMdx: true +--- + +import Callout from "../../components/docs/callout.tsx"; +import Form from "../../components/docs/exampleOptionForm.astro"; + +You can try out different combinations of technologies that create-t3-app offers. + + + You cannot select `prisma` and `drizzle` at the same time. + + +
+ + + Some features might not work unless you create an env file + diff --git a/www/src/pages/id/faq.mdx b/www/src/pages/id/faq.mdx new file mode 100644 index 0000000000..1271158411 --- /dev/null +++ b/www/src/pages/id/faq.mdx @@ -0,0 +1,76 @@ +--- +title: FAQ +description: Frequently asked questions about Create T3 App +layout: ../../layouts/docs.astro +lang: en +isMdx: true +--- + +import Callout from "../../components/docs/callout.tsx"; + +Here are some commonly asked questions about Create T3 App. + +## What's next? How do I make an app with this? + +We try to keep this project as simple as possible, so you can start with just the scaffolding we set up for you, and add additional things later when they become necessary. + +If you are not familiar with the different technologies used in this project, please refer to the respective docs. If you still are in the wind, please join our [Discord](https://t3.gg/discord) and ask for help. + +- [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) + +## How do I keep my app up to date? + +Create T3 App is a scaffolding tool, not a framework. This means that once you initialize an app, it's yours. There is no postinstall CLI tool similar to help you stay up to date. If you want to keep track of any improvements we make to the template, you could [enable notifications for releases](https://docs.github.com/en/account-and-profile/managing-subscriptions-and-notifications-on-github/setting-up-notifications/configuring-notifications#configuring-your-watch-settings-for-an-individual-repository) on our repository. That being said it is not really necessary to implement every change we make to the template in your app. + +## What learning resources are currently available? + +Although the resources listed below are some of the best that exist for the T3 Stack, the community (and [Theo](https://youtu.be/rzwaaWH0ksk?t=1436)) recommend that you just start using the stack and learn along the way by building with it. + +If you are considering Create T3 App, chances are you might have already used some of the parts of the stack. So why not just dive in head first and learn the other parts while you build something? + +Now, we realize this path doesn't work for everyone. So, if you feel like you've tried the recommendation and would still like some resources, or you just aren't confident doing it by yourself and/or feel overwhelmed by the stack, checkout these awesome tutorials on Create T3 App: + +### Articles + +Some of these might be outdated. + +- [A first look at Create T3 App](https://dev.to/ajcwebdev/a-first-look-at-create-t3-app-1i8f) +- [Migrating your T3 App into a Turborepo](https://www.jumr.dev/blog/t3-turbo) +- [Integrating Stripe into your T3 App](https://blog.nickramkissoon.com/posts/integrate-stripe-t3) + +### Videos + +- [T3 Stack Tutorial - FROM 0 TO PROD FOR $0 (Next.js, tRPC, TypeScript, Tailwind, Prisma & More)](https://www.youtube.com/watch?v=YkOSUVzOAA4) **(recommended)** +- [Jack Herrington - Build a Note Taking app with the T3 Stack](https://www.youtube.com/watch?v=J1gzN1SAhyM) +- [Build a Twitter Clone with the T3 Stack - tRPC, Next.js, Prisma, Tailwind & Zod](https://www.youtube.com/watch?v=nzJsYJPCc80) +- [Build a Blog With the T3 Stack - tRPC, TypeScript, Next.js, Prisma & Zod](https://www.youtube.com/watch?v=syEWlxVFUrY) +- [Build a Live Chat Application with the T3 Stack - TypeScript, Tailwind, tRPC](https://www.youtube.com/watch?v=dXRRY37MPuk) +- [The T3 Stack - How We Built It](https://www.youtube.com/watch?v=H-FXwnEjSsI) +- [An overview of the Create T3 App (Next, Typescript, Tailwind, tRPC, Next-Auth)](https://www.youtube.com/watch?v=VJH8dsPtbeU) + +## Why are there `.js` files in the project? + +As per [T3-Axiom #3](/en/introduction#typesafety-isnt-optional), we treat typesafety as a first class citizen. Unfortunately, not all frameworks and plugins support TypeScript which means some of the configuration files have to be `.js` files. + +We try to emphasize that these files are JavaScript for a reason, by explicitly declaring each file's type (`cjs` or `mjs`) depending on what's supported by the library it is used by. Also, all the `js` files in this project are still typechecked using a checkJs option in the compiler (tsconfig). + +## I'm struggling to add i18n to my app. Is there any reference I can use? + +We have decided against including i18n by default in `create-t3-app` because it's a very opinionated topic and there are many ways to implement it. + +However, if you struggle to implement it and want to see a reference project, we have a [reference repo](https://github.com/juliusmarminge/t3-i18n) that shows how you can add i18n to a T3 App using [next-i18next](https://github.com/i18next/next-i18next). + +## Why are we using `/pages` and not `/app` from Next.js 13? + +As per [T3-Axiom #2](/en/introduction#bleed-responsibly), we love bleeding edge stuff but value stability, your entire router is hard to port, [not a great place to bleed](https://youtu.be/mnwUbtieOuI?t=1662). While `/app` is [a glimpse into the future](https://youtu.be/rnsC-12PVlM?t=818), it's not ready for production; The API is in beta and expected to have breaking changes. + + + For a list of supported, planned, and worked on features in the `/app` dir, + visit the [beta Next.js + docs](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..446e910953 --- /dev/null +++ b/www/src/pages/id/folder-structure.mdx @@ -0,0 +1,212 @@ +--- +title: Folder Structure +description: Folder structure of a newly scaffolded T3 App +layout: ../../layouts/docs.astro +lang: en +isMdx: true +--- + +import Diagram from "../../components/docs/folderStructureDiagram.astro"; +import Form from "../../components/docs/folderStructureForm.astro"; + +Please select your packages to see the folder structure of a newly scaffolded app with those selections. Further down, you will find a description of each entry. + + + + + +
+ +### `prisma` + +The `prisma` folder contains the `schema.prisma` file which is used to configure the database connection and the database schema. It is also the location to store migration files and/or seed scripts, if used. See [Prisma usage](/en/usage/prisma) for more information. + +
+
+ +### `public` + +The `public` folder contains static assets that are served by the web server. The `favicon.ico` file is an example of a static asset. + +
+
+ +### `src/env` + +Used for environment variable validation and type definitions - see [Environment Variables](usage/env-variables). + +
+
+ +### `src/pages` + +The `pages` folder contains all the pages of the Next.js application. The `index.tsx` file at the root directory of `/pages` is the homepage of the application. The `_app.tsx` file is used to wrap the application with providers. See [Next.js documentation](https://nextjs.org/docs/basic-features/pages) for more information. + +
+
+ +#### `src/pages/api` + +The `api` folder contains all the API routes of the Next.js application. See [Next.js Api Routes Docs](https://nextjs.org/docs/api-routes/introduction) for info on api routes. + +
+
+ +#### `src/pages/api/auth/[...nextauth].ts` + +The `[...nextauth].ts` file is the NextAuth.js authentication slug route. It is used to handle authentication requests. See [NextAuth.js usage](usage/next-auth) for more information on NextAuth.js, and [Next.js Dynamic Routes Docs](https://nextjs.org/docs/routing/dynamic-routes) for info on catch-all/slug routes. + +
+
+ +#### `src/pages/api/trpc/[trpc].ts` + +The `[trpc].ts` file is the tRPC API entrypoint. It is used to handle tRPC requests. See [tRPC usage](usage/trpc#-pagesapitrpctrpcts) for more information on this file, and [Next.js Dynamic Routes Docs](https://nextjs.org/docs/routing/dynamic-routes) for info on catch-all/slug routes. + +
+
+ +### `src/server` + +The `server` folder is used to clearly separate server-side code from client-side code. + +
+
+ +#### `src/server/auth.ts` + +The main entrypoint for server-side authentication logic. Here, we setup the NextAuth.js [configuration options](usage/next-auth), perform [module augmentation](usage/next-auth#inclusion-of-userid-on-the-session) as well as provide some DX utilities for authentication such as retrieving the user's session on the server-side. See [NextAuth.js usage](usage/next-auth#usage-with-trpc) for more information. + +
+
+ +#### `src/server/db.ts` + +The `db.ts` file is used to instantiate the Prisma client at global scope. See [Prisma usage](usage/prisma#prisma-client) and [best practices for using Prisma with Next.js](https://www.prisma.io/docs/guides/database/troubleshooting-orm/help-articles/nextjs-prisma-client-dev-practices) for more information. + +
+
+ +### `src/server/api` + +The `api` folder contains the tRPC server-side code. + +
+
+ +#### `src/server/api/routers` + +The `routers` folder contains all your tRPC sub-routers. + +
+
+ +#### `src/server/api/routers/example.ts` + +The `example.ts` file is an example tRPC router utilizing the `publicProcedure` helper to demonstrate how to create a public tRPC route. + +Depending on your chosen packages this router contains more or less routes to best demonstrate the usage to your needs. + +
+
+ +#### `src/server/api/trpc.ts` + +The `trpc.ts` file is the main configuration file for your tRPC back-end. In here we: + +1. Define context used in tRPC requests. See [tRPC usage](usage/trpc#-serverapitrpcts) for more information. +2. Export procedure helpers. See [tRPC usage](usage/trpc#-serverapitrpcts) for more information. + +
+ +
+ +#### `src/server/api/root.ts` + +The `root.ts` file is used to merge tRPC routers and export them as a single router, as well as the router's type definition. See [tRPC usage](usage/trpc#-serverapirootts) for more information. + +
+
+ +### `src/styles` + +The `styles` folder contains the global styles of the application. + +
+
+ +### `src/utils` + +The `utils` folder is used to store commonly re-used utility functions. + +
+
+ +#### `src/utils/api.ts` + +The `api.ts` file is the front-end entrypoint to tRPC. See [tRPC usage](usage/trpc#-utilsapits) for more information. + +
+
+ +### `.env` + +The `.env` file is used to store environment variables. See [Environment Variables](usage/env-variables) for more information. This file should **not** be committed to git history. + +
+
+ +### `.env.example` + +The `.env.example` file shows example environment variables based on the chosen libraries. This file should be committed to git history. + +
+
+ +### `.eslintrc.cjs` + +The `.eslintrc.cjs` file is used to configure ESLint. See [ESLint Docs](https://eslint.org/docs/latest/user-guide/configuring/configuration-files) for more information. + +
+
+ +### `next-env.d.ts` + +The `next-env.d.ts` file ensures Next.js types are picked up by the TypeScript compiler. **You should not remove it or edit it as it can change at any time.** See [Next.js Docs](https://nextjs.org/docs/basic-features/typescript#existing-projects) for more information. + +
+
+ +### `next.config.mjs` + +The `next.config.mjs` file is used to configure Next.js. See [Next.js Docs](https://nextjs.org/docs/api-reference/next.config.js/introduction) for more information. Note: The .mjs extension is used to allow for ESM imports. + +
+
+ +### `postcss.config.cjs` + +The `postcss.config.cjs` file is used for Tailwind PostCSS usage. See [Tailwind PostCSS Docs](https://tailwindcss.com/docs/installation/using-postcss) for more information. + +
+
+ +### `prettier.config.mjs` + +The `prettier.config.mjs` file is used to configure Prettier to include the prettier-plugin-tailwindcss for formatting Tailwind CSS classes. See the [Tailwind CSS blog post](https://tailwindcss.com/blog/automatic-class-sorting-with-prettier) for more information. + +
+
+ +### `tsconfig.json` + +The `tsconfig.json` file is used to configure TypeScript. Some non-defaults, such as `strict mode`, have been enabled to ensure the best usage of TypeScript for Create T3 App and its libraries. See [TypeScript Docs](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html) or [TypeScript Usage](usage/typescript) for more information. + +
+
+ +### `drizzle.config.ts` + +The `drizzle.config.ts` file is used to configure drizzle kit. See [the documentation](https://orm.drizzle.team/kit-docs/config-reference) for more information. + +
\ No newline at end of file diff --git a/www/src/pages/id/installation.mdx b/www/src/pages/id/installation.mdx new file mode 100644 index 0000000000..17df75d4e2 --- /dev/null +++ b/www/src/pages/id/installation.mdx @@ -0,0 +1,72 @@ +--- +title: Installation +description: Installation instructions for Create T3 App +layout: ../../layouts/docs.astro +lang: en +isMdx: true +--- + +import Callout from "../../components/docs/callout.tsx"; + +To scaffold an app using `create-t3-app`, run any of the following three commands and answer the command prompt questions: + +### 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 +``` + +After your app has been scaffolded, check out the [first steps](/en/usage/first-steps) to get started on your new application. + +## Advanced usage + +| Option/Flag | Description | +| ----------------- | ----------------------------------------------------------------------- | +| `[dir]` | Include a directory argument with a name for the project | +| `--noGit` | Explicitly tell the CLI to not initialize a new git repo in the project | +| `-y`, `--default` | Bypass the CLI and bootstrap a new t3-app with all options selected | +| `--noInstall` | Generate project without installing dependencies | + +## Experimental usage + +For our CI, we have some experimental flags that allow you to scaffold any app without any prompts. If this use case applies to you, you can use these flags. Please note that these flags are experimental and may change in the future without following semver versioning. + +| Flag | Description | +| ------------ | ----------------------------------- | +| `--CI` | Let the CLI know you're in CI mode | +| `--trpc` | Include tRPC in the project | +| `--prisma` | Include Prisma in the project | +| `--nextAuth` | Include NextAuth.js in the project | +| `--tailwind` | Include Tailwind CSS in the project | + + + If you don't provide the `CI` flag, the rest of these flags has no effect. + + +You don't need to explicitly opt-out of the packages you don't want. However, if you prefer to be explicit, you can pass `false`, e.g. `--nextAuth false`. + +### Example + +The following would scaffold a T3 App with tRPC and Tailwind CSS. + +```bash +pnpm dlx create-t3-app@latest --CI --trpc --tailwind +``` diff --git a/www/src/pages/id/other-recs.md b/www/src/pages/id/other-recs.md new file mode 100644 index 0000000000..d3319ccaae --- /dev/null +++ b/www/src/pages/id/other-recs.md @@ -0,0 +1,163 @@ +--- +title: Other Recommendations +description: Libraries and Services that we recommend for many projects +layout: ../../layouts/docs.astro +lang: en +--- + +We recognize that the libraries included in `create-t3-app` don't solve every problem. While we encourage you to begin your project with the things that we provide, there will come a time when you need to bring in other packages. Only you can know what your project needs, but here are some things that we find ourselves recommending frequently. + +These are recommendations by individual Create T3 App contributors and should not be seen as "official" endorsements by the Create T3 App team or T3-OSS. _**Please do your own research, especially before committing to paid services**_. + +## State Management + +_**Editor's Note**_: State management libraries can be great, but often aren't necessary. tRPC's React Query hooks should be able to take care of your server state. For client state, start with React's `useState`, and reach for one of these options when you need more. + +### Zustand + +**For never using Redux again** + +The "modern, simple Redux" you didn't know you needed. [Poimandres](https://github.com/pmndrs) can always be trusted. You can build everything from video call apps to games to servers with this little library. + +- [Zustand Homepage](https://zustand-demo.pmnd.rs/) +- [Zustand GitHub](https://github.com/pmndrs/zustand) + +### Jotai + +**For never using Context again** + +For a more atomic approach, Jotai is hard to beat. Also by [Poimandres](https://github.com/pmndrs), Jotai lets you define singletons that feel like global useState. A great option for stateful behaviors that don't need a state machine just yet. + +- [Jotai Homepage](https://jotai.org/) +- [Jotai GitHub](https://github.com/pmndrs/jotai) + +## Component Libraries + +Most apps need the same handful of components - toggle buttons, dropdown menus, modals, and so on. These libraries provide great, accessible components that you can use and customize to your liking. + +### Unstyled Component Libraries + +Also known as headless libraries, they provide great unstyled, and accessible components that you can customize to your liking. Here are a few recommendations. + +- [Radix UI](https://www.radix-ui.com/) gives you a powerful set of convenient and accessible primitives that you can style with vanilla or Tailwind CSS. + +- [Headless UI](https://headlessui.com/) made by the Tailwind CSS team also provides unstyled, accessible components that integrate seamlessly with Tailwind CSS. + +- [React Aria](https://react-spectrum.adobe.com/react-aria/) provides accessible UI primitives for your design system. Their Date Picker component is top tier. + +### Styled Component Libraries + +**For when you just want your app to look OK** + +Sometimes you're building a project where you just want the UI to look decent out of the box. For Admin Dashboards and other similar projects, any of these component libraries will get the job done. + +- [Chakra UI](https://chakra-ui.com) +- [Mantine](https://mantine.dev) +- [@shadcn/ui](https://ui.shadcn.com/) + +### Class Variance Authority + +**For building UI Libraries** + +Declaratively build a UI Library with different color, size, etc. variants. When your project reaches a scale where you want a standardized set of UI components with multiple variants using Tailwind CSS, CVA is a great tool. + +- [Class Variance Authority GitHub](https://github.com/joe-bell/cva) + +## Animations + +For when you need animations in your app, here are our recommendations. + +### AutoAnimate + +**For animations with a single line of code** + +Most animation libraries try to satisfy every possible use case, and become clunky as a result. AutoAnimate is a zero-configuration tool that will give you a significant improvement in UX with no additional developer effort. + +- [AutoAnimate Homepage](https://auto-animate.formkit.com/) +- [AutoAnimate GitHub](https://github.com/formkit/auto-animate) +- [AutoAnimate Component Snippet](https://gist.github.com/hwkr/3fdea5d7f609b98c162e5325637cf3cb) + +### Framer Motion + +**For complex animations with declarative code** + +Framer Motion provides a simple, declarative syntax and allows you to write less code to craft everything from complex animations to even gestures. + +- [Framer Motion Homepage](https://framer.com/motion) +- [Framer Motion Documentation](https://www.framer.com/docs/) + +## Deployments, Infrastructure, Databases and CI + +### Vercel + +**For hosting your app** + +Vercel took the hell of web deployments and made it a set-and-forget GitHub integration. We've scaled to hundreds of thousands of users without issue. AWS-powered, just a way better interface :) + +- [Vercel Homepage](https://vercel.com/) +- [Create T3 App Vercel deployment guide](/en/deployment/vercel) + +### PlanetScale + +**For databases without the worry** + +PlanetScale is the best "serverless database platform" we've used by far. Insane scale, great developer experience, and fantastic pricing. If you're using SQL (and hopefully Prisma), this is hard to beat. + +- [PlanetScale Homepage](https://planetscale.com/) + +### Railway + +**For hosting your infra** + +"Modern Heroku". The easiest way to get a real server up and running. If Vercel and PlanetScale aren't enough, Railway probably is. Point it at a GitHub repo and go. + +- [Railway Homepage](https://railway.app/) + +### Upstash + +**For serverless Redis** + +We love Prisma and PlanetScale, but some projects require a more performant solution. Upstash allows you to get the in-memory performance of Redis in your serverless project, without having to manage the infrastructure and scaling yourself. + +- [Upstash Homepage](https://upstash.com/) + +### Pusher + +**For serverless WebSockets** + +If WebSockets are the primary focus of your project, you may want to consider a more traditional backend such as [Fastify](https://www.fastify.io/) (which [also works with tRPC!](https://trpc.io/docs/v10/fastify)). But for quickly adding WebSockets to a T3 App, Pusher is an excellent choice. + +- [Pusher Homepage](https://pusher.com/) + +### Soketi + +Soketi is a self-hostable, simple, and fast alternative to Pusher. It's fully compatible with the Pusher SDK which you can use to connect to the server. Soketi serverless is also in beta. + +- [Soketi Homepage](https://soketi.app) +- [Soketi GitHub](https://github.com/soketi/soketi) + +## Analytics + +User data is very valuable when you're building an app. Here are some analytics providers we recommend. + +### Plausible + +Need analytics? Plausible is one of the quickest ways to get them. Super minimal. It even has a [simple plugin for Next.js](https://plausible.io/docs/proxy/guides/nextjs). + +- [Plausible Homepage](https://plausible.io/) + +### Umami + +Umami is an open-sourced, self-hostable, simple, fast, privacy-focused alternative to Google Analytics. You can deploy it really easily to Vercel, Railway, etc. with PlanetScale as your database or you can also use its cloud version. + +- [Umami Homepage](https://umami.is/) +- [Umami GitHub](https://github.com/umami-software/umami) +- [Umami Cloud](https://cloud.umami.is/) + +## Other + +### Next Bundle Analyzer + +It can sometimes be difficult to determine what will be included in the build output for your app. Next Bundle Analyzer is an easy way to visualize and analyze the JavaScript bundles that are generated. + +- [@next/bundle-analyzer on 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..8c8cfcb9b1 --- /dev/null +++ b/www/src/pages/id/t3-collection.mdx @@ -0,0 +1,29 @@ +--- +title: T3 Collection +description: Cool open source projects and companies using the T3 stack +layout: ../../layouts/docs.astro +lang: en +isMdx: true +--- + +import OpenSourceAppList from "../../components/docs/openSourceAppList.tsx"; +import CompanyList from "../../components/docs/companyList.tsx"; +import Callout from "../../components/docs/callout.tsx"; + +Made a project using the T3 stack and want to share it? Add it to the list! + +## Open Source apps made using the T3 Stack + + + +## Companies using the T3 Stack + +We'd love to know of companies that use the T3 stack for their apps. Is your company using the T3 stack and would like to share it? Add it to the list! + + + + + Have a cool project using the T3 stack? Make a [pull + request](https://github.com/t3-oss/create-t3-app/tree/next/www/src/components/docs/openSourceAppList.tsx) + and add it here! + diff --git a/www/src/pages/id/usage/drizzle.mdx b/www/src/pages/id/usage/drizzle.mdx new file mode 100644 index 0000000000..aefe547554 --- /dev/null +++ b/www/src/pages/id/usage/drizzle.mdx @@ -0,0 +1,14 @@ +--- +title: Drizzle +description: Usage of Drizzle +layout: ../../../layouts/docs.astro +lang: en +isMdx: true +--- + +import Callout from "../../../components/docs/callout.tsx"; + + + The `drizzle` option is a new addition and no docs have yet been written. Contributions are welcome! + + 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..888dbcab63 --- /dev/null +++ b/www/src/pages/id/usage/env-variables.mdx @@ -0,0 +1,149 @@ +--- +title: Environment Variables +description: Getting started with Create T3 App +layout: ../../../layouts/docs.astro +lang: en +isMdx: true +--- + +import Callout from "../../../components/docs/callout.tsx"; + +Create T3 App uses its own package [@t3-oss/env-nextjs](https://env.t3.gg) along with [zod](https://zod.dev) under the hood for validating environment variables at runtime _and_ buildtime by providing a simple logic in `src/env.mjs`. + +## env.mjs + +_TLDR; If you want to add a new environment variable, you must add a validator for it in `src/env.mjs`, and then add the KV-pair in `.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 uses the `createEnv` function to create the schema validate both client and server-side environment variables. + + + For more information about how `createEnv` works internally, check out the [T3 + Env](https://env.t3.gg/docs/introduction) docs + + +## Using Environment Variables + +When you want to use your environment variables, you can import them from the created `env.mjs` and use them as you would normally do. If you import this on the client and try accessing a server-side environment variable, you will get a runtime error. + +```ts:pages/api/hello.ts +import { env } from "../../env.mjs"; + +// `env` is fully typesafe and provides autocompletion +const dbUrl = env.DATABASE_URL; +``` + +```ts:pages/index.tsx +import { env } from "../env.mjs"; + +// ❌ This will throw a runtime error +const dbUrl = env.DATABASE_URL; + +// ✅ This is fine +const wsKey = env.NEXT_PUBLIC_WS_KEY; +``` + +## .env.example + +Since the default `.env` file is not committed to version control, we have also included a `.env.example` file, in which you can optionally keep a copy of your `.env` file with any secrets removed. This is not required, but we recommend keeping the example up to date to make it as easy as possible for contributors to get started with their environment. + +Some frameworks and build tools, like Next.js, suggest that you store secrets in a `.env.local` file and commit `.env` files to your project. This is not recommended, as it could make it easy to accidentally commit secrets to your project. Instead, we recommend that you store secrets in `.env`, keep your `.env` file in your `.gitignore` and only commit `.env.example` files to your project. + +## Adding Environment Variables + +To ensure your build never completes without the environment variables the project needs, you will need to add new environment variables in **two** locations: + +📄 `.env`: Enter your environment variable like you would normally do in a `.env` file, i.e. `KEY=VALUE` + +📄 `env.mjs`: Add the appropriate validation logic for the environment variables by defining a Zod schema inside `createEnv` for each one, e.g. `KEY: z.string()`. Besides that, make sure to destruct them in the `runtimeEnv` option, e.g.: `KEY: process.env.KEY` + + + Why do I need to destructure the environment variable in the `runtimeEnv`? + This is due to how Next.js bundles environment variables in certain runtimes. + By destructuring it manually, you ensure that the variable will never be + stripped out from the bundle. + + +Optionally, you can also keep `.env.example` updated: + +📄 `.env.example`: Enter your environment variable, but be sure to not include the value if it is secret, i.e. `KEY=VALUE` or `KEY=` + +### Example + +_I want to add my Twitter API Token as a server-side environment variable_ + +1. Add the environment variable to `.env`: + +``` +TWITTER_API_TOKEN=1234567890 +``` + +2. Add the environment variable to `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. _Optional:_ Add the environment variable to `.env.example` and make sure not to include the secret in the `runtimeEnv` option + +```bash +TWITTER_API_TOKEN= +``` + +## Type Coercion + +All variables you add to `.env` will be imported as strings, even if their value is intended to represent a different type. If you want to use your environment variables as a different type at runtime, you can use Zod's `coerce` to convert the string to the type you want. It will throw if the coercion fails. + +Add the variables to your `.env`: + +``` +SOME_NUMBER=123 +SOME_BOOLEAN=true +``` + +Then, validate them in `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, + }, +}); +``` 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..776f3ce8ff --- /dev/null +++ b/www/src/pages/id/usage/first-steps.md @@ -0,0 +1,50 @@ +--- +title: First Steps +description: Getting started with your new T3 App +layout: ../../../layouts/docs.astro +lang: en +--- + +You just scaffolded a new T3 App and are ready to go. Here is the bare minimum to get your app working. + +## Database + +### Prisma + +If your app includes Prisma, make sure to run `npx prisma db push` from the root directory of your app. This command will sync your Prisma schema with your database and will generate the TypeScript types for the Prisma Client based on your schema. Note that you need to [restart the TypeScript server](https://tinytip.co/tips/vscode-restart-ts/) after doing this so that it can detect the generated types. + +### Drizzle + +If your app includes Drizzle, check the `.env` file for instructions on how to construct your `DATABASE_URL` env variable. Once your env file is ready, run `pnpm db:push` (or the equivalent for other package managers) to push your schema. + +## Authentication + +If your app includes NextAuth.js, we get you started with the `DiscordProvider`. This is one of the simplest providers that NextAuth.js offers, but it still requires a bit of initial setup on your part. + +Of course, if you prefer to use a different auth provider, you can also use one of the [many providers](https://next-auth.js.org/providers/) that NextAuth.js offers. + +1. You will need a Discord account, so register one if you haven't already. +2. Navigate to https://discord.com/developers/applications and click "New Application" in the top right corner. Give your application a name and agree to the Terms of Service. +3. Once your application has been created, navigate to "Settings → OAuth2 → General". +4. Copy the "Client ID" and add it to your `.env` as `DISCORD_CLIENT_ID`. +5. Click "Reset Secret", copy the new secret, and add it to your `.env` as `DISCORD_CLIENT_SECRET`. +6. Click "Add Redirect" and type in `http://localhost:3000/api/auth/callback/discord`. + - For production deployment, follow the previous steps to create another Discord Application, but this time replace `http://localhost:3000` with the URL that you are deploying to. +7. Save Changes. +8. Set the `NEXTAUTH_SECRET` in `.env`. In development any string will work, for production see the note in `.env` on generating a secure secret. + +You should now be able to log in. + +## Editor Setup + +The following extensions are recommended for an optimal developer experience. The links below provide editor specific plugin support. + +- [Prisma Extension](https://www.prisma.io/docs/guides/development-environment/editor-setup) +- [Tailwind CSS IntelliSense Extension](https://tailwindcss.com/docs/editor-setup) +- [Prettier Extension](https://prettier.io/docs/en/editors.html) + +## Next Steps + +- If your app includes tRPC, check out `src/pages/index.tsx` and `src/server/api/routers/post.ts` to see how tRPC queries work. +- Have a look around the Create T3 App docs, as well as the docs of the packages that your app includes. +- Join our [Discord](https://t3.gg/discord) and give us a star on [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..4c31ec7bf1 --- /dev/null +++ b/www/src/pages/id/usage/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: "Usage", + layout: "docs", + description: "Learn how to use the different technology from the T3 Stack.", +}; + +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..cb0830caf5 --- /dev/null +++ b/www/src/pages/id/usage/next-auth.mdx @@ -0,0 +1,228 @@ +--- +title: NextAuth.js +description: Usage of NextAuth.js +layout: ../../../layouts/docs.astro +lang: en +isMdx: true +--- + +import Callout from "../../../components/docs/callout.tsx"; + +When you want an authentication system in your Next.js application, NextAuth.js is an excellent solution to bring in the complexity of security without the hassle of having to build it yourself. It comes with an extensive list of providers to quickly add OAuth authentication and provides adapters for many databases and ORMs. + +## Context Provider + +In your app's entrypoint, you'll see that your application is wrapped in a [SessionProvider](https://next-auth.js.org/getting-started/client#sessionprovider): + +```tsx:pages/_app.tsx + + + +``` + +This context provider allows your application to access the session data from anywhere in your application, without having to pass it down as props: + +```tsx:pages/users/[id].tsx +import { useSession } from "next-auth/react"; + +const User = () => { + const { data: session } = useSession(); + + if (!session) { + // Handle unauthenticated state, e.g. render a SignIn component + return ; + } + + return

Welcome {session.user.name}!

; +}; +``` + +## Retrieving session server-side + +Sometimes you might want to request the session on the server. To do so, prefetch the session using the `getServerAuthSession` helper function that `create-t3-app` provides, and pass it down to the client using `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(); + // NOTE: `session` wont have a loading state since it's already prefetched on the server + + ... +} +``` + +## Inclusion of `user.id` on the Session + +Create T3 App is configured to utilise the [session callback](https://next-auth.js.org/configuration/callbacks#session-callback) in the NextAuth.js config to include the user's ID within the `session` object. + +```ts:server/auth.ts +callbacks: { + session({ session, user }) { + if (session.user) { + session.user.id = user.id; + } + return session; + }, + }, +``` + +This is coupled with a type declaration file to make sure the `user.id` is typed when accessed on the `session` object. Read more about [`Module Augmentation`](https://next-auth.js.org/getting-started/typescript#module-augmentation) on NextAuth.js's docs. + +```ts:server/auth.ts +import { DefaultSession } from "next-auth"; + +declare module "next-auth" { + interface Session { + user?: { + id: string; + } & DefaultSession["user"]; + } +} +``` + +The same pattern can be used to add any other data to the `session` object, such as a `role` field, but **should not be misused to store sensitive data** on the client. + +## Usage with tRPC + +When using NextAuth.js with tRPC, you can create reusable, protected procedures using [middleware](https://trpc.io/docs/v10/middlewares). This allows you to create procedures that can only be accessed by authenticated users. `create-t3-app` sets all of this up for you, allowing you to easily access the session object within authenticated procedures. + +This is done in a two step process: + +1. Grab the session from the request headers using the [`getServerSession`](https://next-auth.js.org/configuration/nextjs#getServerSession) function. The advantage of using `getServerSession` instead of the regular `getSession` is that it's a server-side only function and doesn't trigger unnecessary fetch calls. `create-t3-app` creates a helper function that abstracts this peculiar API away so that you don't need to import both your NextAuth.js options as well as the `getServerSession` function every time you need to access the session. + +```ts:server/auth.ts +export const getServerAuthSession = (ctx: { + req: GetServerSidePropsContext["req"]; + res: GetServerSidePropsContext["res"]; +}) => { + return getServerSession(ctx.req, ctx.res, authOptions); +}; +``` + +Using this helper function, we can grab the session and pass it through to the tRPC context: + +```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. Create a tRPC middleware that checks if the user is authenticated. We then use the middleware in a `protectedProcedure`. Any caller to these procedures must be authenticated, or else an error will be thrown which can be appropriately handled by the client. + +```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: { + // infers the `session` as non-nullable + session: { ...ctx.session, user: ctx.session.user }, + }, + }); +}); + +export const protectedProcedure = t.procedure.use(isAuthed); +``` + +The session object is a light, minimal representation of the user and only contains a few fields. When using the `protectedProcedures`, you have access to the user's id which can be used to fetch more data from the database. + +```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; + }), +}); +``` + +## Usage with Prisma + +Getting NextAuth.js to work with Prisma requires a lot of [initial setup](https://authjs.dev/reference/adapter/prisma/). `create-t3-app` handles all of this for you, and if you select both Prisma and NextAuth.js, you'll get a fully working authentication system with all the required models preconfigured. We ship your scaffolded app with a preconfigured Discord OAuth provider, which we chose because it is one of the easiest to get started with - just provide your tokens in the `.env` and you're good to go. However, you can easily add more providers by following the [NextAuth.js docs](https://next-auth.js.org/providers/). Note that certain providers require extra fields to be added to certain models. We recommend you read the documentation for the provider you would like to use to make sure you have all the required fields. + +### Adding new fields to your models + +When adding new fields to any of the `User`, `Account`, `Session`, or `VerificationToken` models (most likely you'd only need to modify the `User` model), you need to keep in mind that the [Prisma adapter](https://next-auth.js.org/adapters/prisma) automatically creates fields on these models when new users sign up and log in. Therefore, when adding new fields to these models, you must provide default values for them, since the adapter is not aware of these fields. + +If for example, you'd like to add a `role` to the `User` model, you would need to provide a default value to the `role` field. This is done by adding a `@default` value to the `role` field in the `User` model: + +```diff:prisma/schema.prisma ++ enum Role { ++ USER ++ ADMIN ++ } + + model User { + ... ++ role Role @default(USER) + } +``` + +## Usage with Next.js middleware + +Usage of NextAuth.js with Next.js middleware [requires the use of the JWT session strategy](https://next-auth.js.org/configuration/nextjs#caveats) for authentication. This is because the middleware is only able to access the session cookie if it is a JWT. By default, Create T3 App is configured to use the **default** database strategy, in combination with Prisma as the database adapter. + + + Using database sessions is the recommended approach and you should read up on JWTs before switching to the JWT session strategy to avoid any security issues. + + +After switching to the JWT session strategy. Make sure to update the `session` callback in `src/server/auth.ts`. +The `user` object will be `undefined`. Instead, retrieve the user's ID from the `token` object. +I.e.: + +```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; + } + }), + }, + }; +``` + +## Setting up the default DiscordProvider + +1. Head to [the Applications section in the Discord Developer Portal](https://discord.com/developers/applications), and click on "New Application" +2. In the settings menu, go to "OAuth2 => General" + +- Copy the Client ID and paste it in `DISCORD_CLIENT_ID` in `.env`. +- Under Client Secret, click "Reset Secret" and copy that string to `DISCORD_CLIENT_SECRET` in `.env`. Be careful as you won't be able to see this secret again, and resetting it will cause the existing one to expire. +- Click "Add Redirect" and paste in `/api/auth/callback/discord` (example for local development: http://localhost:3000/api/auth/callback/discord) +- Save your changes +- It is possible, but not recommended, to use the same Discord Application for both development and production. You could also consider [Mocking the Provider](https://github.com/trpc/trpc/blob/main/examples/next-prisma-websockets-starter/src/pages/api/auth/%5B...nextauth%5D.ts) during development. + +## Useful Resources + +| Resource | Link | +| --------------------------------- | --------------------------------------- | +| NextAuth.js Docs | https://next-auth.js.org/ | +| NextAuth.js GitHub | https://github.com/nextauthjs/next-auth | +| tRPC Kitchen Sink - with NextAuth | https://kitchen-sink.trpc.io/next-auth | 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..77bf718134 --- /dev/null +++ b/www/src/pages/id/usage/next-js.md @@ -0,0 +1,37 @@ +--- +title: Next.js +description: Usage of Next.js +layout: ../../../layouts/docs.astro +lang: en +--- + +Next.js is a backend framework for your React applications. + +
+ +
+ +Check out [Theo's Next.js Conf talk](https://www.youtube.com/watch?v=W4UhNo3HAMw) to get a better understanding of what Next.js is and how it works.

+ +## Why should I use it? + +We love React. It has made UI development accessible in ways we never imagined before. It also can lead developers down some rough paths. Next.js offers a lightly opinionated, heavily optimized approach to creating applications using React. From routing to API definitions to image rendering, we trust Next.js to lead developers towards good decisions. + +Pairing Next.js with [Vercel](https://vercel.com/) makes developing and deploying web apps easier than ever before. Their extremely generous free-tier and super intuitive interface provides a point and click solution to deploy your site (We ❤️ Vercel) + +## Get Static/Server Props + +A key feature of Next.js is its data fetching capabilities. We highly recommend reading through the [official documentation](https://nextjs.org/docs/basic-features/data-fetching) to understand how to use each method and how they differ. `getServerSideProps` is generally discouraged unless there is a good reason for it, due to the fact that it is a blocking call and will slow down your site. [Incremental Static Regeneration](https://nextjs.org/docs/basic-features/data-fetching/incremental-static-regeneration) is a great alternative to `getServerSideProps` when the data is dynamic and can be fetched incrementally. + +If you need to use this feature anyway, check these links out: [Advanced tRPC - Callers, functions, and gSSP](https://www.youtube.com/watch?v=G2ZzmgShHgQ) and [SSG-Helpers](https://trpc.io/docs/v9/ssg-helpers) + +## Useful Resources + +| Resource | Link | +| ------------------------------ | ---------------------------------- | +| Next.js Documentation | https://nextjs.org/docs | +| Next.js GitHub | https://github.com/vercel/next.js | +| Next.js Blog | https://nextjs.org/blog | +| Next.js Discord | https://nextjs.org/discord | +| Next.js Twitter | https://twitter.com/nextjs | +| Vercel/Next.js YouTube Channel | https://www.youtube.com/c/VercelHQ | diff --git a/www/src/pages/id/usage/prisma.md b/www/src/pages/id/usage/prisma.md new file mode 100644 index 0000000000..7dead0698e --- /dev/null +++ b/www/src/pages/id/usage/prisma.md @@ -0,0 +1,78 @@ +--- +title: Prisma +description: Usage of Prisma +layout: ../../../layouts/docs.astro +lang: en +--- + +Prisma is an ORM for TypeScript, that allows you to define your database schema and models in a `schema.prisma` file, and then generate a type-safe client that can be used to interact with your database from your backend. + +## Prisma Client + +Located at `src/server/db.ts`, the Prisma Client is instantiated as a global variable (as recommended as [best practice](https://www.prisma.io/docs/guides/database/troubleshooting-orm/help-articles/nextjs-prisma-client-dev-practices#problem) by the team at Prisma) and exported to be used in your API routes. We include the Prisma Client in [Context](/en/usage/trpc#-serverapitrpcts) by default and recommend using this instead of importing it separately in each file. + +## Schema + +You will find the Prisma schema file at `/prisma/schema.prisma`. This file is where you define your database schema and models, and is used when generating the Prisma Client. + +### With NextAuth.js + +When you select NextAuth.js in combination with Prisma, the schema file is generated and set up for you with the recommended values for the `User`, `Session`, `Account`, and `VerificationToken` models, as per the [NextAuth.js documentation](https://next-auth.js.org/adapters/prisma). + +## Default Database + +The default database is an SQLite database, which is great for development and quickly spinning up a proof-of-concept but is not recommended for production. You can change the database to use by changing the `provider` in the `datasource` block to either `postgresql` or `mysql`, and then updating the connection string within environment variables to point to your database. + +## Seeding your Database + +[Seeding your database](https://www.prisma.io/docs/guides/database/seed-database) is a great way to quickly populate your database with test data to help you get started. In order to setup seeding, you will need to create a `seed.ts` file in the `/prisma` directory, and then add a `seed` script to your `package.json` file. You'll also need some TypeScript runner that can execute the seed-script. We recommend [tsx](https://github.com/esbuild-kit/tsx), which is a very performant TypeScript runner that uses esbuild and doesn't require any ESM configuration, but `ts-node` or other runners will work as well. + +```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); + }); +``` + +Then, just run `pnpm db-seed` (or `npm`/`yarn`) to seed your database. + +## Useful Resources + +| Resource | Link | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| Prisma Docs | https://www.prisma.io/docs/ | +| Prisma GitHub | https://github.com/prisma/prisma | +| Prisma Migrate Playground | https://playground.prisma.io/guides | +| NextAuth.JS Prisma Adapter | https://next-auth.js.org/adapters/prisma | +| Planetscale Connection Guide | https://www.prisma.io/docs/getting-started/setup-prisma/add-to-existing-project/relational-databases/connect-your-database-typescript-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..bdb355a4b0 --- /dev/null +++ b/www/src/pages/id/usage/tailwind.md @@ -0,0 +1,96 @@ +--- +title: Tailwind CSS +description: Usage of Tailwind CSS +layout: ../../../layouts/docs.astro +lang: en +--- + +## What is Tailwind CSS? + +Tailwind CSS is a tiny, [utility first](https://tailwindcss.com/docs/utility-first) CSS framework for building custom designs, without the context switching that regular CSS requires. It is purely a CSS framework and does not provide any pre-built components or logic, and provides [a very different set of benefits](https://www.youtube.com/watch?v=CQuTF-bkOgc) compared to a component library like Material UI. + +It makes CSS incredibly easy and quick to write, as shown by the following example: + +Old CSS: + +1. Write CSS, often in a separate file + +```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. Import CSS into your component + +```jsx +import "./my-class.css"; +``` + +3. Add the class to your HTML + +```html +
...
+``` + +Equivalent in Tailwind: + +1. Just write classes in your HTML + +```html +
+ ... +
+``` + +When used together with React Components, it is extremely powerful for quickly building UIs. + +Tailwind CSS has a beautiful built-in design system, that comes out of the box with a carefully chosen color palette, sizing patterns for styles such as width/height and padding/margin for a uniform design, as well as media breakpoints for creating responsive layouts. This design system can be customized and extended to create the exact toolbox of styles that your project needs. + +
+ +
+ +Tru Narla better known as [mewtru](https://twitter.com/trunarla) gave an amazing talk on [building a design system using Tailwind CSS](https://www.youtube.com/watch?v=T-Zv73yZ_QI). + +## Usage + +Make sure you have editor plugins for Tailwind installed to improve your experience writing Tailwind. + +### Extensions and Plugins + +- [VSCode Extension](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss) +- [JetBrains Integration](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) + +### Formatting + +Tailwind CSS classes can easily get a bit messy, so a formatter for the classes is a must have. [Tailwind CSS Prettier Plugin](https://github.com/tailwindlabs/prettier-plugin-tailwindcss) sorts the classes in the [recommended order](https://tailwindcss.com/blog/automatic-class-sorting-with-prettier#how-classes-are-sorted) so that the classes match the outputted css bundle. When selecting Tailwind in the CLI, we will install and configure this for you. + +### Conditionally Applying Classes + +Conditionally adding classes using ternaries can get very messy and hard to read. These packages help in organizing your classes when using some conditional logic. + +- [clsx](https://github.com/lukeed/clsx) +- [classnames](https://github.com/JedWatson/classnames) + +## Useful Resources + +| Resource | Link | +| ---------------------------- | -------------------------------------------------------- | +| Tailwind Docs | https://tailwindcss.com/docs/editor-setup/ | +| Tailwind Cheat Sheet | https://nerdcave.com/tailwind-cheat-sheet/ | +| awesome-tailwindcss | https://github.com/aniftyco/awesome-tailwindcss/ | +| Tailwind Community | https://github.com/tailwindlabs/tailwindcss/discussions/ | +| Tailwind Discord Server | https://tailwindcss.com/discord/ | +| TailwindLabs Youtube Channel | https://www.youtube.com/tailwindlabs/ | +| Tailwind Playground | https://play.tailwindcss.com/ | diff --git a/www/src/pages/id/usage/trpc.md b/www/src/pages/id/usage/trpc.md new file mode 100644 index 0000000000..789311d17f --- /dev/null +++ b/www/src/pages/id/usage/trpc.md @@ -0,0 +1,382 @@ +--- +title: tRPC +description: Usage of tRPC +layout: ../../../layouts/docs.astro +lang: en +--- + +tRPC allows us to write end-to-end typesafe APIs without any code generation or runtime bloat. It uses TypeScript's great inference to infer your API router's type definitions and lets you call your API procedures from your frontend with full typesafety and autocompletion. When using tRPC, your frontend and backend feel closer together than ever before, allowing for an outstanding developer experience. + +
+
+

+ I built tRPC to allow people to move faster by removing the need of a traditional API-layer, while still having confidence that our apps won't break as we rapidly iterate. +

+
+ + Avatar of @alexdotjs +
+ Alex - creator of tRPC + + @alexdotjs + +
+
+
+ +## How do I use tRPC? + +
+ +
+ +tRPC contributor [trashh_dev](https://twitter.com/trashh_dev) made [a killer talk at Next.js Conf](https://www.youtube.com/watch?v=2LYM8gf184U) about tRPC. We highly recommend you watch it if you haven't already. + +With tRPC, you write TypeScript functions on your backend, and then call them from your frontend. A simple tRPC procedure could look like this: + +```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, + }, + }); + }), +}); +``` + +This is a tRPC procedure (equivalent to a route handler in a traditional backend) that first validates the input using Zod (which is the same validation library that we use for [environment variables](./env-variables)) - in this case, it's making sure that the input is a string. If the input is not a string it will send an informative error instead. + +After the input, we chain a resolver function which can be either a [query](https://trpc.io/docs/v10/react-queries), [mutation](https://trpc.io/docs/v10/react-mutations), or a [subscription](https://trpc.io/docs/v10/subscriptions). In our example, the resolver calls our database using our [prisma](./prisma) client and returns the user whose `id` matches the one we passed in. + +You define your procedures in `routers` which represent a collection of related procedures with a shared namespace. You may have one router for `users`, one for `posts`, and another one for `messages`. These routers can then be merged into a single, centralized `appRouter`: + +```ts:server/api/root.ts +const appRouter = createTRPCRouter({ + users: userRouter, + posts: postRouter, + messages: messageRouter, +}); + +export type AppRouter = typeof appRouter; +``` + +Notice that we only need to export our router's type definitions, which means we are never importing any server code on our client. + +Now let's call the procedure on our frontend. tRPC provides a wrapper for `@tanstack/react-query` which lets you utilize the full power of the hooks they provide, but with the added benefit of having your API calls typed and inferred. We can call our procedures from our frontend like this: + +```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}

+
+ ); +}; +``` + +You'll immediately notice how good the autocompletion and typesafety is. As soon as you write `api.`, your routers will show up in autocomplete, and when you select a router, its procedures will show up as well. You'll also get a TypeScript error if your input doesn't match the validator that you defined on the backend. + +## Inferring errors + +By default, `create-t3-app` sets up an [error formatter](https://trpc.io/docs/error-formatting) that lets you infer your Zod Errors if you get validation errors on the backend. + +Example usage: + +```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?.fieldErrors.title && ( + {/** `mutate` returned with an error on the `title` */} + + {error.data.zodError.fieldErrors.title} + + )} + + ... + + ); +} +``` + +## Files + +tRPC requires quite a lot of boilerplate that `create-t3-app` sets up for you. Let's go over the files that are generated: + +### 📄 `pages/api/trpc/[trpc].ts` + +This is the entry point for your API and exposes the tRPC router. Normally, you won't touch this file very much, but if you need to, for example, enable CORS middleware or similar, it's useful to know that the exported `createNextApiHandler` is a [Next.js API handler](https://nextjs.org/docs/api-routes/introduction) which takes a [request](https://developer.mozilla.org/en-US/docs/Web/API/Request) and [response](https://developer.mozilla.org/en-US/docs/Web/API/Response) object. This means that you can wrap the `createNextApiHandler` in any middleware you want. See below for an [example snippet](#enabling-cors) of adding CORS. + +### 📄 `server/api/trpc.ts` + +This file is split up in two parts, context creation and tRPC initialization: + +1. We define the context that is passed to your tRPC procedures. Context is data that all of your tRPC procedures will have access to, and is a great place to put things like database connections, authentication information, etc. In create-t3-app we use two functions, to enable using a subset of the context when we do not have access to the request object. + +- `createInnerTRPCContext`: This is where you define context which doesn't depend on the request, e.g. your database connection. You can use this function for [integration testing](#sample-integration-test) or [ssg-helpers](https://trpc.io/docs/v10/ssg-helpers) where you don't have a request object. + +- `createTRPCContext`: This is where you define context which depends on the request, e.g. the user's session. You request the session using the `opts.req` object, and then pass the session down to the `createInnerTRPCContext` function to create the final context. + +2. We initialize tRPC and define reusable [procedures](https://trpc.io/docs/v10/procedures) and [middlewares](https://trpc.io/docs/v10/middlewares). By convention, you shouldn't export the entire `t`-object but instead, create reusable procedures and middlewares and export those. + +You'll notice we use `superjson` as [data transformer](https://trpc.io/docs/v10/data-transformers). This makes it so that your data types are preserved when they reach the client, so if you for example send a `Date` object, the client will return a `Date` and not a string which is the case for most APIs. + +### 📄 `server/api/routers/*.ts` + +This is where you define the routes and procedures of your API. By convention, you [create separate routers](https://trpc.io/docs/v10/router) for related procedures. + +### 📄 `server/api/root.ts` + +Here we [merge](https://trpc.io/docs/v10/merging-routers) all the sub-routers defined in `routers/**` into a single app router. + +### 📄 `utils/api.ts` + +This is the frontend entry point for tRPC. This is where you'll import the router's **type definition** and create your tRPC client along with the react-query hooks. Since we enabled `superjson` as our data transformer on the backend, we need to enable it on the frontend as well. This is because the serialized data from the backend is deserialized on the frontend. + +You'll define your tRPC [links](https://trpc.io/docs/v10/links) here, which determines the request flow from the client to the server. We use the "default" [`httpBatchLink`](https://trpc.io/docs/v10/links/httpBatchLink) which enables [request batching](https://cloud.google.com/compute/docs/api/how-tos/batch), as well as a [`loggerLink`](https://trpc.io/docs/v10/links/loggerLink) which outputs useful request logs during development. + +Lastly, we export a [helper type](https://trpc.io/docs/v10/infer-types#additional-dx-helper-type) which you can use to infer your types on the frontend. + +
+ +
+ +Create T3 App contributor [Christopher Ehrlich](https://twitter.com/ccccjjjjeeee) made [a video about data flows in tRPC](https://www.youtube.com/watch?v=x4mu-jOiA0Q). This video is recommended if you have used tRPC but still feel a bit unclear about how it works. + +## How do I call my API externally? + +With regular APIs, you can call your endpoints using any HTTP client such as `curl`, `Postman`, `fetch` or straight from your browser. With tRPC, it's a bit different. If you want to call your procedures without the tRPC client, there are two recommended ways to do it: + +### Expose a single procedure externally + +If you want to expose a single procedure externally, you're looking for [server side calls](https://trpc.io/docs/v10/server-side-calls). That would allow you to create a normal Next.js API endpoint, but reuse the resolver part of your tRPC procedure. + +```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) => { + // Create context and caller + 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) { + // An error from tRPC occured + const httpCode = getHTTPStatusCodeFromError(cause); + return res.status(httpCode).json(cause); + } + // Another error occured + console.error(cause); + res.status(500).json({ message: "Internal server error" }); + } +}; + +export default userByIdHandler; +``` + +### Exposing every procedure as a REST endpoint + +If you want to expose every single procedure externally, checkout the community built plugin [trpc-openapi](https://github.com/jlalmes/trpc-openapi/tree/master). By providing some extra meta-data to your procedures, you can generate an OpenAPI compliant REST API from your tRPC router. + +### It's just HTTP Requests + +tRPC communicates over HTTP, so it is also possible to call your tRPC procedures using "regular" HTTP requests. However, the syntax can be cumbersome due to the [RPC protocol](https://trpc.io/docs/v10/rpc) that tRPC uses. If you're curious, you can check what tRPC requests and responses look like in your browser's network tab, but we suggest doing this only as an educational exercise and sticking to one of the solutions outlined above. + +## Comparison to a Next.js API endpoint + +Let's compare a Next.js API endpoint to a tRPC procedure. Let's say we want to fetch a user object from our database and return it to the frontend. We could write a Next.js API endpoint like this: + +```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: "Invalid id" }); + } + + 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]); +}; +``` + +Compare this to the tRPC example above and you can see some of the advantages of tRPC: + +- Instead of specifying a url for each route, which can become annoying to debug if you move something, your entire router is an object with autocomplete. +- You don’t need to validate which HTTP method was used. +- You don’t need to validate that the request query or body contains the correct data in the procedure, because Zod takes care of this. +- Instead of creating a response, you can throw errors and return a value or object as you would in any other TypeScript function. +- Calling the procedure on the frontend provides autocompletion and type safety. + +## Useful snippets + +Here are some snippets that might come in handy. + +### Enabling CORS + +If you need to consume your API from a different domain, for example in a monorepo that includes a React Native app, you might need to enable 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) => { + // Enable cors + await cors(req, res); + + // Create and call the tRPC handler + return createNextApiHandler({ + router: appRouter, + createContext: createTRPCContext, + })(req, res); +}; + +export default handler; +``` + +### Optimistic updates + +Optimistic updates are when we update the UI before the API call has finished. This gives the user a better experience because they don't have to wait for the API call to finish before the UI reflects the result of their action. However, apps that value data correctness highly should avoid optimistic updates as they are not a "true" representation of backend state. You can read more on the [React Query docs](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) { + // Cancel outgoing fetches (so they don't overwrite our optimistic update) + await utils.post.list.cancel(); + + // Get the data from the queryCache + const prevData = utils.post.list.getData(); + + // Optimistically update the data with our new post + utils.post.list.setData(undefined, (old) => [...old, newPost]); + + // Return the previous data so we can revert if something goes wrong + return { prevData }; + }, + onError(err, newPost, ctx) { + // If the mutation fails, use the context-value from onMutate + utils.post.list.setData(undefined, ctx.prevData); + }, + onSettled() { + // Sync with server once mutation has settled + utils.post.list.invalidate(); + }, + }); +}; +``` + +### Sample Integration Test + +Here is a sample integration test that uses [Vitest](https://vitest.dev) to check that your tRPC router is working as expected, the input parser infers the correct type, and that the returned data matches the expected output. + +```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("example router", async () => { + const ctx = await createInnerTRPCContext({ session: null }); + const caller = appRouter.createCaller(ctx); + + type Input = inferProcedureInput; + const input: Input = { + text: "test", + }; + + const example = await caller.example.hello(input); + + expect(example).toMatchObject({ greeting: "Hello test" }); +}); +``` + +If your procedure is protected, you can pass in a mocked `session` object when you create the context: + +```ts +test("protected example router", async () => { + const ctx = await createInnerTRPCContext({ + session: { + user: { id: "123", name: "John Doe" }, + expires: "1", + }, + }); + const caller = appRouter.createCaller(ctx); + + // ... +}); +``` + +## Useful Resources + +| Resource | Link | +| ---------------------- | ------------------------------------------------------- | +| tRPC Docs | https://www.trpc.io | +| Bunch of tRPC Examples | https://github.com/trpc/trpc/tree/next/examples | +| React Query Docs | https://tanstack.com/query/v4/docs/adapters/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..833fd5b2bc --- /dev/null +++ b/www/src/pages/id/usage/typescript.md @@ -0,0 +1,67 @@ +--- +title: TypeScript +description: Usage of TypeScript +layout: ../../../layouts/docs.astro +lang: en +--- + +
+
+

+ Build safety nets, not guard rails +

+
+ + Avatar of @t3dotgg +
+ Theo - creator of the T3 Stack + + @t3dotgg + +
+
+
+ +Whether you're a new or seasoned developer, we think that TypeScript is a must have. It can look intimidating at first, but much like a lot of tools, is something that many never look back from after starting to use it. + +It provides live feedback as you write your code by defining expected data types, and either provides helpful autocomplete in your code editor, or yells at you with red squiggly lines if you're trying to access a property that doesn't exist or trying to pass a value of the wrong type, which you would otherwise have to debug further down the line. + +It is, perhaps, the tool that provides the most productivity to developers; providing documentation of the code you're writing or consuming directly in your editor, and having instant feedback as you inevitably make mistakes is absolutely priceless. + +## Type Inference + +While many new TypeScript developers are concerned with _writing_ TypeScript, many of its benefits don't actually require you to change your code at all, in particular inference. Inference means that if something is typed, that type will follow it throughout the flow of the application without having to be re-declared in other places. This means that for example once you have defined the types of the arguments that a function takes, the remainder of the function will usually be typesafe without requiring any further TypeScript-specific code. Library developers put a ton of work into maintaining the types for their libraries, which means that we as application developers can benefit from both the inference and the built-in documentation in your code editor that these types provide. + +
+ +
+ +Check out Theo's video on how [you might be using TypeScript wrong](https://www.youtube.com/watch?v=RmGHnYUqQ4k). + +## Powerful uses of type inference + +### Zod + +[Zod](https://github.com/colinhacks/zod) is a schema validation library that is built on top of TypeScript. Write a schema that represents a single source of truth for your data, and Zod will ensure that your data is valid throughout your application, even across network boundaries and external APIs. + +### Tanstack Query + +[Tanstack Query](https://tanstack.com/query/v4/) gives you declarative, always-up-to-date auto-managed queries and mutations that directly improve both your developer and user experiences. + +## Useful Resources + +| Resource | Link | +| --------------------------------------------------------- | ----------------------------------------------------------------- | +| TypeScript Handbook | https://www.typescriptlang.org/docs/handbook/ | +| Beginners TypeScript Tutorial | https://github.com/total-typescript/beginners-typescript-tutorial | +| Type Challenges | https://github.com/type-challenges/type-challenges | +| Rodney Mullen of TypeScript (Matt Pocock) Youtube Channel | https://www.youtube.com/c/MattPocockUk/videos | diff --git a/www/src/pages/id/why.md b/www/src/pages/id/why.md new file mode 100644 index 0000000000..035a30beab --- /dev/null +++ b/www/src/pages/id/why.md @@ -0,0 +1,50 @@ +--- +title: Why CT3A? +description: Why you should pick Create T3 App for your next project +layout: ../../layouts/docs.astro +lang: en +--- + +We started Create T3 App because [Theo](https://twitter.com/t3dotgg) refused to make a template of his favorite technologies. Inspired by create-next-app, [Astro's CLI](https://astro.build) and a general love for typesafety, the Create T3 App team worked hard to build the best possible starting point for new T3 Stack projects. + +If you're interested in using Next.js in a typesafe way, this is the place to start. If you're curious about any of the specific technology choices we made, read on :) + +## Why TypeScript? + +JavaScript is hard. Why add more rules? + +We firmly believe the experience TypeScript provides will help you be a better developer. It provides live feedback as you write your code by defining expected data types, and either provides helpful autocomplete in your editor or yells at you with red squiggly lines if you're trying to access a property that doesn't exist or trying to pass a value of the wrong type, which you would otherwise have to debug further down the line. Whether you're new to web development or a seasoned pro, the "strictness" of TypeScript will provide a less frustrating, more consistent experience than vanilla JS. + +Typesafety makes you faster. If you're not convinced, you [might be using TypeScript wrong...](https://www.youtube.com/watch?v=RmGHnYUqQ4k) + +## Why Next.js? + +We love React. It has made UI development accessible in ways we never imagined before. It also can lead developers down some rough paths. + +Next.js offers a lightly opinionated, heavily optimized approach to creating applications using React. From routing to API definitions to image rendering, we trust Next.js to lead developers toward good decisions. + +## Why tRPC/Prisma/Tailwind/etc? + +While we believe in keeping things as simple as possible, we find these pieces being used in every "app" like project we build. `create-t3-app` does a great job of letting you adopt the pieces you need. + +### tRPC + +tRPC delivers on GraphQL's promise of seamless client development against a typesafe server without all of the boilerplate. It's a clever abuse of TypeScript that provides an incredible dev experience. + +### Prisma + +Prisma is to SQL what TypeScript is to JS. It created a developer experience that didn't exist before. By generating types from a user-defined schema compatible with [several databases](https://www.prisma.io/docs/concepts/database-connectors), Prisma guarantees end-to-end typesafety from your database to your app. + +Prisma provides a whole [suite of tools](https://www.prisma.io/docs/concepts/overview/should-you-use-prisma#-you-want-a-tool-that-holistically-covers-your-database-workflows) making daily interactions with your database easier. Notably, the Prisma Client is responsible for querying and making SQL so easy you'll barely notice you're using it, and Prisma Studio is a convenient GUI for your database that lets you read and manipulate your data quickly without having to write code. + +### Tailwind CSS + +Tailwind feels like "zen-mode CSS". + +By providing building blocks in the form of good default colors, spacing, and other primitives, Tailwind makes it easy to create a good-looking app. And unlike component libraries, it does not hold you back when you want to take your app to the next level and create something beautiful and unique. + +Additionally, with its inline-like approach, Tailwind encourages you to style without worrying about naming classes, organizing files, or any other issue not directly tied to the problem you're trying to solve. + +### NextAuth.js + +When you want an authentication system in your NextJS application, NextAuth.js is an excellent solution to bring in the complexity of security without the hassle of having to build it yourself. It comes with an extensive list of providers to quickly add OAuth authentication and provides adapters for many databases and ORMs. From 38f9db881b1f52bb468e020a7c36bb74ede4d748 Mon Sep 17 00:00:00 2001 From: Imamuzzaki Abu Salam Date: Mon, 30 Oct 2023 09:01:45 +0700 Subject: [PATCH 02/13] docs: translate introduction to id --- www/src/pages/id/introduction.md | 42 ++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 www/src/pages/id/introduction.md 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. From f283c984bb778a5f9f908b2813789f3c8e7dec2f Mon Sep 17 00:00:00 2001 From: Imamuzzaki Abu Salam Date: Mon, 30 Oct 2023 09:03:44 +0700 Subject: [PATCH 03/13] feat: Add Bahasa Indonesia language option --- www/src/config.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/www/src/config.ts b/www/src/config.ts index 7e0418636c..81777799b4 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: "Русский", From d24998cb21369d79fd1c6ce951098fa0ed3e9d7e Mon Sep 17 00:00:00 2001 From: Imamuzzaki Abu Salam Date: Mon, 30 Oct 2023 09:06:40 +0700 Subject: [PATCH 04/13] feat(config.ts): add Indonesian translation for sidebar --- www/src/config.ts | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/www/src/config.ts b/www/src/config.ts index 81777799b4..4eb8bd691b 100644 --- a/www/src/config.ts +++ b/www/src/config.ts @@ -166,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" }, @@ -402,6 +433,11 @@ export const SIDEBAR_HEADER_MAP: Record< Usage: "كيفية الإستخدام؟", Deployment: "نَشر تطبيقك", }, + id: { + "Create T3 App": "Create T3 App", + Usage: "Pemakaian", + Deployment: "Penyebaran", + }, fr: { "Create T3 App": "Create T3 App", Usage: "Utilisation", From 905f6562f0941848c3cd24ac27a1484de84fbe54 Mon Sep 17 00:00:00 2001 From: Imamuzzaki Abu Salam Date: Mon, 30 Oct 2023 09:10:18 +0700 Subject: [PATCH 05/13] refactor: Update why.md with Indonesian translations --- www/src/pages/id/why.md | 42 ++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/www/src/pages/id/why.md b/www/src/pages/id/why.md index 035a30beab..1702bdc765 100644 --- a/www/src/pages/id/why.md +++ b/www/src/pages/id/why.md @@ -1,50 +1,50 @@ --- -title: Why CT3A? -description: Why you should pick Create T3 App for your next project +title: Mengapa CT3A? +description: Mengapa Anda harus memilih Create T3 App untuk proyek selanjutnya layout: ../../layouts/docs.astro -lang: en +lang: id --- -We started Create T3 App because [Theo](https://twitter.com/t3dotgg) refused to make a template of his favorite technologies. Inspired by create-next-app, [Astro's CLI](https://astro.build) and a general love for typesafety, the Create T3 App team worked hard to build the best possible starting point for new T3 Stack projects. +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. -If you're interested in using Next.js in a typesafe way, this is the place to start. If you're curious about any of the specific technology choices we made, read on :) +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 :) -## Why TypeScript? +## Mengapa TypeScript? -JavaScript is hard. Why add more rules? +JavaScript itu sulit. Mengapa menambah lebih banyak aturan? -We firmly believe the experience TypeScript provides will help you be a better developer. It provides live feedback as you write your code by defining expected data types, and either provides helpful autocomplete in your editor or yells at you with red squiggly lines if you're trying to access a property that doesn't exist or trying to pass a value of the wrong type, which you would otherwise have to debug further down the line. Whether you're new to web development or a seasoned pro, the "strictness" of TypeScript will provide a less frustrating, more consistent experience than vanilla JS. +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 makes you faster. If you're not convinced, you [might be using TypeScript wrong...](https://www.youtube.com/watch?v=RmGHnYUqQ4k) +Typesafety membuat Anda lebih cepat. Jika Anda belum yakin, Anda [mungkin menggunakan TypeScript dengan cara yang salah...](https://www.youtube.com/watch?v=RmGHnYUqQ4k) -## Why Next.js? +## Mengapa Next.js? -We love React. It has made UI development accessible in ways we never imagined before. It also can lead developers down some rough paths. +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 offers a lightly opinionated, heavily optimized approach to creating applications using React. From routing to API definitions to image rendering, we trust Next.js to lead developers toward good decisions. +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. -## Why tRPC/Prisma/Tailwind/etc? +## Mengapa tRPC/Prisma/Tailwind/dll? -While we believe in keeping things as simple as possible, we find these pieces being used in every "app" like project we build. `create-t3-app` does a great job of letting you adopt the pieces you need. +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 delivers on GraphQL's promise of seamless client development against a typesafe server without all of the boilerplate. It's a clever abuse of TypeScript that provides an incredible dev experience. +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 is to SQL what TypeScript is to JS. It created a developer experience that didn't exist before. By generating types from a user-defined schema compatible with [several databases](https://www.prisma.io/docs/concepts/database-connectors), Prisma guarantees end-to-end typesafety from your database to your app. +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 provides a whole [suite of tools](https://www.prisma.io/docs/concepts/overview/should-you-use-prisma#-you-want-a-tool-that-holistically-covers-your-database-workflows) making daily interactions with your database easier. Notably, the Prisma Client is responsible for querying and making SQL so easy you'll barely notice you're using it, and Prisma Studio is a convenient GUI for your database that lets you read and manipulate your data quickly without having to write code. +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 feels like "zen-mode CSS". +Tailwind terasa seperti "CSS mode zen". -By providing building blocks in the form of good default colors, spacing, and other primitives, Tailwind makes it easy to create a good-looking app. And unlike component libraries, it does not hold you back when you want to take your app to the next level and create something beautiful and unique. +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. -Additionally, with its inline-like approach, Tailwind encourages you to style without worrying about naming classes, organizing files, or any other issue not directly tied to the problem you're trying to solve. +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 -When you want an authentication system in your NextJS application, NextAuth.js is an excellent solution to bring in the complexity of security without the hassle of having to build it yourself. It comes with an extensive list of providers to quickly add OAuth authentication and provides adapters for many databases and ORMs. +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. From 2fe9d6069ef25481a2454cae9d480299bcf4b202 Mon Sep 17 00:00:00 2001 From: Imamuzzaki Abu Salam Date: Mon, 30 Oct 2023 09:11:30 +0700 Subject: [PATCH 06/13] docs: translate t3-collection.mdx to id --- www/src/pages/id/t3-collection.mdx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/www/src/pages/id/t3-collection.mdx b/www/src/pages/id/t3-collection.mdx index 8c8cfcb9b1..e53af25841 100644 --- a/www/src/pages/id/t3-collection.mdx +++ b/www/src/pages/id/t3-collection.mdx @@ -1,8 +1,8 @@ --- -title: T3 Collection -description: Cool open source projects and companies using the T3 stack +title: Koleksi T3 +description: Proyek open source keren dan perusahaan yang menggunakan stack T3 layout: ../../layouts/docs.astro -lang: en +lang: id isMdx: true --- @@ -10,20 +10,20 @@ import OpenSourceAppList from "../../components/docs/openSourceAppList.tsx"; import CompanyList from "../../components/docs/companyList.tsx"; import Callout from "../../components/docs/callout.tsx"; -Made a project using the T3 stack and want to share it? Add it to the list! +Membuat proyek menggunakan stack T3 dan ingin membagikannya? Tambahkan ke daftar! -## Open Source apps made using the T3 Stack +## Aplikasi Open Source yang dibuat menggunakan Stack T3 -## Companies using the T3 Stack +## Perusahaan yang menggunakan Stack T3 -We'd love to know of companies that use the T3 stack for their apps. Is your company using the T3 stack and would like to share it? Add it to the list! +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! - Have a cool project using the T3 stack? Make a [pull + 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) - and add it here! + dan tambahkan di sini! From e60d1979079924fe5dd85e0bb0a7ec616a1acdd7 Mon Sep 17 00:00:00 2001 From: Imamuzzaki Abu Salam Date: Mon, 30 Oct 2023 09:16:01 +0700 Subject: [PATCH 07/13] docs: translate other-recs.md to id --- www/src/pages/id/other-recs.md | 104 ++++++++++++++++----------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/www/src/pages/id/other-recs.md b/www/src/pages/id/other-recs.md index d3319ccaae..b2494d3b57 100644 --- a/www/src/pages/id/other-recs.md +++ b/www/src/pages/id/other-recs.md @@ -1,163 +1,163 @@ --- -title: Other Recommendations -description: Libraries and Services that we recommend for many projects +title: Rekomendasi Lainnya +description: Perpustakaan dan Layanan yang kami rekomendasikan untuk banyak proyek layout: ../../layouts/docs.astro -lang: en +lang: id --- -We recognize that the libraries included in `create-t3-app` don't solve every problem. While we encourage you to begin your project with the things that we provide, there will come a time when you need to bring in other packages. Only you can know what your project needs, but here are some things that we find ourselves recommending frequently. +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. -These are recommendations by individual Create T3 App contributors and should not be seen as "official" endorsements by the Create T3 App team or T3-OSS. _**Please do your own research, especially before committing to paid services**_. +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**_. -## State Management +## Manajemen State -_**Editor's Note**_: State management libraries can be great, but often aren't necessary. tRPC's React Query hooks should be able to take care of your server state. For client state, start with React's `useState`, and reach for one of these options when you need more. +_**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 -**For never using Redux again** +**Untuk tidak pernah menggunakan Redux lagi** -The "modern, simple Redux" you didn't know you needed. [Poimandres](https://github.com/pmndrs) can always be trusted. You can build everything from video call apps to games to servers with this little library. +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 -**For never using Context again** +**Untuk tidak pernah menggunakan Context lagi** -For a more atomic approach, Jotai is hard to beat. Also by [Poimandres](https://github.com/pmndrs), Jotai lets you define singletons that feel like global useState. A great option for stateful behaviors that don't need a state machine just yet. +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) -## Component Libraries +## Perpustakaan Komponen -Most apps need the same handful of components - toggle buttons, dropdown menus, modals, and so on. These libraries provide great, accessible components that you can use and customize to your liking. +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. -### Unstyled Component Libraries +### Perpustakaan Komponen Tanpa Gaya -Also known as headless libraries, they provide great unstyled, and accessible components that you can customize to your liking. Here are a few recommendations. +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/) gives you a powerful set of convenient and accessible primitives that you can style with vanilla or Tailwind CSS. +- [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/) made by the Tailwind CSS team also provides unstyled, accessible components that integrate seamlessly with 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/) provides accessible UI primitives for your design system. Their Date Picker component is top tier. +- [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. -### Styled Component Libraries +### Perpustakaan Komponen Dengan Gaya -**For when you just want your app to look OK** +**Untuk saat Anda hanya ingin tampilan aplikasi Anda terlihat baik** -Sometimes you're building a project where you just want the UI to look decent out of the box. For Admin Dashboards and other similar projects, any of these component libraries will get the job done. +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/) -### Class Variance Authority +### Otoritas Varians Kelas -**For building UI Libraries** +**Untuk membangun Perpustakaan UI** -Declaratively build a UI Library with different color, size, etc. variants. When your project reaches a scale where you want a standardized set of UI components with multiple variants using Tailwind CSS, CVA is a great tool. +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) -## Animations +## Animasi -For when you need animations in your app, here are our recommendations. +Ketika Anda membutuhkan animasi dalam aplikasi Anda, berikut rekomendasi kami. ### AutoAnimate -**For animations with a single line of code** +**Untuk animasi dengan satu baris kode** -Most animation libraries try to satisfy every possible use case, and become clunky as a result. AutoAnimate is a zero-configuration tool that will give you a significant improvement in UX with no additional developer effort. +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) -- [AutoAnimate Component Snippet](https://gist.github.com/hwkr/3fdea5d7f609b98c162e5325637cf3cb) +- [Potongan Kode Komponen AutoAnimate](https://gist.github.com/hwkr/3fdea5d7f609b98c162e5325637cf3cb) ### Framer Motion -**For complex animations with declarative code** +**Untuk animasi kompleks dengan kode yang deklaratif** -Framer Motion provides a simple, declarative syntax and allows you to write less code to craft everything from complex animations to even gestures. +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) -- [Framer Motion Documentation](https://www.framer.com/docs/) +- [Dokumentasi Framer Motion](https://www.framer.com/docs/) -## Deployments, Infrastructure, Databases and CI +## Penyimpanan, Infrastruktur, Basis Data, dan CI ### Vercel -**For hosting your app** +**Untuk hosting aplikasi Anda** -Vercel took the hell of web deployments and made it a set-and-forget GitHub integration. We've scaled to hundreds of thousands of users without issue. AWS-powered, just a way better interface :) +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/) -- [Create T3 App Vercel deployment guide](/en/deployment/vercel) +- [Panduan penyebaran Create T3 App Vercel](/id/deployment/vercel) ### PlanetScale -**For databases without the worry** +**Untuk basis data tanpa kekhawatiran** -PlanetScale is the best "serverless database platform" we've used by far. Insane scale, great developer experience, and fantastic pricing. If you're using SQL (and hopefully Prisma), this is hard to beat. +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 -**For hosting your infra** +**Untuk hosting infrastruktur Anda** -"Modern Heroku". The easiest way to get a real server up and running. If Vercel and PlanetScale aren't enough, Railway probably is. Point it at a GitHub repo and go. +"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 -**For serverless Redis** +**Untuk Redis serverless** -We love Prisma and PlanetScale, but some projects require a more performant solution. Upstash allows you to get the in-memory performance of Redis in your serverless project, without having to manage the infrastructure and scaling yourself. +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 -**For serverless WebSockets** +**Untuk WebSockets serverless** -If WebSockets are the primary focus of your project, you may want to consider a more traditional backend such as [Fastify](https://www.fastify.io/) (which [also works with tRPC!](https://trpc.io/docs/v10/fastify)). But for quickly adding WebSockets to a T3 App, Pusher is an excellent choice. +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 is a self-hostable, simple, and fast alternative to Pusher. It's fully compatible with the Pusher SDK which you can use to connect to the server. Soketi serverless is also in beta. +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) -## Analytics +## Analitik -User data is very valuable when you're building an app. Here are some analytics providers we recommend. +Data pengguna sangat berharga saat Anda membangun aplikasi. Berikut beberapa penyedia analitik yang kami rekomendasikan. ### Plausible -Need analytics? Plausible is one of the quickest ways to get them. Super minimal. It even has a [simple plugin for Next.js](https://plausible.io/docs/proxy/guides/nextjs). +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 is an open-sourced, self-hostable, simple, fast, privacy-focused alternative to Google Analytics. You can deploy it really easily to Vercel, Railway, etc. with PlanetScale as your database or you can also use its cloud version. +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/) -## Other +## Lainnya ### Next Bundle Analyzer -It can sometimes be difficult to determine what will be included in the build output for your app. Next Bundle Analyzer is an easy way to visualize and analyze the JavaScript bundles that are generated. +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 on npm](https://www.npmjs.com/package/@next/bundle-analyzer) +- [@next/bundle-analyzer di npm](https://www.npmjs.com/package/@next/bundle-analyzer) From 4a94795b80f2291b1fa251f63d64eda5eb3491b0 Mon Sep 17 00:00:00 2001 From: Imamuzzaki Abu Salam Date: Mon, 30 Oct 2023 09:19:37 +0700 Subject: [PATCH 08/13] docs: translate installation.mdx to id --- www/src/pages/id/installation.mdx | 48 +++++++++++++++---------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/www/src/pages/id/installation.mdx b/www/src/pages/id/installation.mdx index 17df75d4e2..169fa3585e 100644 --- a/www/src/pages/id/installation.mdx +++ b/www/src/pages/id/installation.mdx @@ -1,14 +1,14 @@ --- -title: Installation -description: Installation instructions for Create T3 App +title: Instalasi +description: Instruksi instalasi untuk Create T3 App layout: ../../layouts/docs.astro -lang: en +lang: id isMdx: true --- import Callout from "../../components/docs/callout.tsx"; -To scaffold an app using `create-t3-app`, run any of the following three commands and answer the command prompt questions: +Untuk membuat aplikasi menggunakan `create-t3-app`, jalankan salah satu dari tiga perintah berikut dan jawab pertanyaan dari prompt perintah: ### npm @@ -34,39 +34,39 @@ pnpm create t3-app@latest bun create t3-app@latest ``` -After your app has been scaffolded, check out the [first steps](/en/usage/first-steps) to get started on your new application. +Setelah aplikasi Anda telah dibuat, lihat langkah-langkah pertama [di sini](/id/usage/first-steps) untuk memulai aplikasi baru Anda. -## Advanced usage +## Penggunaan Lanjutan -| Option/Flag | Description | +| Opsi/Flag | Deskripsi | | ----------------- | ----------------------------------------------------------------------- | -| `[dir]` | Include a directory argument with a name for the project | -| `--noGit` | Explicitly tell the CLI to not initialize a new git repo in the project | -| `-y`, `--default` | Bypass the CLI and bootstrap a new t3-app with all options selected | -| `--noInstall` | Generate project without installing dependencies | +| `[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 | -## Experimental usage +## Penggunaan Eksperimental -For our CI, we have some experimental flags that allow you to scaffold any app without any prompts. If this use case applies to you, you can use these flags. Please note that these flags are experimental and may change in the future without following semver versioning. +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 | Description | +| Flag | Deskripsi | | ------------ | ----------------------------------- | -| `--CI` | Let the CLI know you're in CI mode | -| `--trpc` | Include tRPC in the project | -| `--prisma` | Include Prisma in the project | -| `--nextAuth` | Include NextAuth.js in the project | -| `--tailwind` | Include Tailwind CSS in the project | +| `--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 | - If you don't provide the `CI` flag, the rest of these flags has no effect. + Jika Anda tidak menyediakan flag `CI`, maka flag-flag lainnya tidak berpengaruh. -You don't need to explicitly opt-out of the packages you don't want. However, if you prefer to be explicit, you can pass `false`, e.g. `--nextAuth false`. +Anda tidak perlu secara eksplisit menolak paket yang tidak Anda inginkan. Namun, jika Anda lebih suka eksplisit, Anda dapat menyampaikan `false`, misalnya `--nextAuth false`. -### Example +### Contoh -The following would scaffold a T3 App with tRPC and Tailwind CSS. +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 From b0822f719012d833b129e5ee481d1c741674524e Mon Sep 17 00:00:00 2001 From: Imamuzzaki Abu Salam Date: Mon, 30 Oct 2023 09:19:45 +0700 Subject: [PATCH 09/13] docs: translate folder-structure.mdx to id --- www/src/pages/id/folder-structure.mdx | 70 +++++++++++++-------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/www/src/pages/id/folder-structure.mdx b/www/src/pages/id/folder-structure.mdx index 446e910953..214c688edc 100644 --- a/www/src/pages/id/folder-structure.mdx +++ b/www/src/pages/id/folder-structure.mdx @@ -1,15 +1,15 @@ --- -title: Folder Structure -description: Folder structure of a newly scaffolded T3 App +title: Struktur Folder +description: Struktur folder aplikasi T3 yang baru dibuat layout: ../../layouts/docs.astro -lang: en +lang: id isMdx: true --- import Diagram from "../../components/docs/folderStructureDiagram.astro"; import Form from "../../components/docs/folderStructureForm.astro"; -Please select your packages to see the folder structure of a newly scaffolded app with those selections. Further down, you will find a description of each entry. +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.
@@ -19,103 +19,103 @@ Please select your packages to see the folder structure of a newly scaffolded ap ### `prisma` -The `prisma` folder contains the `schema.prisma` file which is used to configure the database connection and the database schema. It is also the location to store migration files and/or seed scripts, if used. See [Prisma usage](/en/usage/prisma) for more information. +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` -The `public` folder contains static assets that are served by the web server. The `favicon.ico` file is an example of a static asset. +Folder `public` berisi aset statis yang disajikan oleh server web. File `favicon.ico` adalah contoh dari aset statis.
### `src/env` -Used for environment variable validation and type definitions - see [Environment Variables](usage/env-variables). +Digunakan untuk validasi variabel lingkungan dan definisi tipe - lihat [Variabel Lingkungan](usage/env-variables).
### `src/pages` -The `pages` folder contains all the pages of the Next.js application. The `index.tsx` file at the root directory of `/pages` is the homepage of the application. The `_app.tsx` file is used to wrap the application with providers. See [Next.js documentation](https://nextjs.org/docs/basic-features/pages) for more information. +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` -The `api` folder contains all the API routes of the Next.js application. See [Next.js Api Routes Docs](https://nextjs.org/docs/api-routes/introduction) for info on api routes. +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` -The `[...nextauth].ts` file is the NextAuth.js authentication slug route. It is used to handle authentication requests. See [NextAuth.js usage](usage/next-auth) for more information on NextAuth.js, and [Next.js Dynamic Routes Docs](https://nextjs.org/docs/routing/dynamic-routes) for info on catch-all/slug routes. +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` -The `[trpc].ts` file is the tRPC API entrypoint. It is used to handle tRPC requests. See [tRPC usage](usage/trpc#-pagesapitrpctrpcts) for more information on this file, and [Next.js Dynamic Routes Docs](https://nextjs.org/docs/routing/dynamic-routes) for info on catch-all/slug routes. +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` -The `server` folder is used to clearly separate server-side code from client-side code. +Folder `server` digunakan untuk memisahkan kode sisi server dengan kode sisi klien.
#### `src/server/auth.ts` -The main entrypoint for server-side authentication logic. Here, we setup the NextAuth.js [configuration options](usage/next-auth), perform [module augmentation](usage/next-auth#inclusion-of-userid-on-the-session) as well as provide some DX utilities for authentication such as retrieving the user's session on the server-side. See [NextAuth.js usage](usage/next-auth#usage-with-trpc) for more information. +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` -The `db.ts` file is used to instantiate the Prisma client at global scope. See [Prisma usage](usage/prisma#prisma-client) and [best practices for using Prisma with Next.js](https://www.prisma.io/docs/guides/database/troubleshooting-orm/help-articles/nextjs-prisma-client-dev-practices) for more information. +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` -The `api` folder contains the tRPC server-side code. +Folder `api` berisi kode sisi server tRPC.
#### `src/server/api/routers` -The `routers` folder contains all your tRPC sub-routers. +Folder `routers` berisi semua sub-router tRPC Anda.
#### `src/server/api/routers/example.ts` -The `example.ts` file is an example tRPC router utilizing the `publicProcedure` helper to demonstrate how to create a public tRPC route. +File `example.ts` adalah contoh router tRPC yang menggunakan helper `publicProcedure` untuk menunjukkan bagaimana membuat rute tRPC publik. -Depending on your chosen packages this router contains more or less routes to best demonstrate the usage to your needs. +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` -The `trpc.ts` file is the main configuration file for your tRPC back-end. In here we: +File `trpc.ts` adalah file konfigurasi utama untuk back-end tRPC Anda. Di sini kami: -1. Define context used in tRPC requests. See [tRPC usage](usage/trpc#-serverapitrpcts) for more information. -2. Export procedure helpers. See [tRPC usage](usage/trpc#-serverapitrpcts) for more information. +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.
@@ -123,90 +123,90 @@ The `trpc.ts` file is the main configuration file for your tRPC back-end. In her #### `src/server/api/root.ts` -The `root.ts` file is used to merge tRPC routers and export them as a single router, as well as the router's type definition. See [tRPC usage](usage/trpc#-serverapirootts) for more information. +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` -The `styles` folder contains the global styles of the application. +Folder `styles` berisi gaya global aplikasi.
### `src/utils` -The `utils` folder is used to store commonly re-used utility functions. +Folder `utils` digunakan untuk menyimpan fungsi utilitas yang sering digunakan.
#### `src/utils/api.ts` -The `api.ts` file is the front-end entrypoint to tRPC. See [tRPC usage](usage/trpc#-utilsapits) for more information. +File `api.ts` adalah titik masuk frontend ke tRPC. Lihat [Penggunaan tRPC](usage/trpc#-utilsapits) untuk informasi lebih lanjut.
### `.env` -The `.env` file is used to store environment variables. See [Environment Variables](usage/env-variables) for more information. This file should **not** be committed to git history. +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` -The `.env.example` file shows example environment variables based on the chosen libraries. This file should be committed to git history. +File `.env.example` menampilkan contoh variabel lingkungan berdasarkan pustaka yang dipilih. File ini harus dicommit ke sejarah git.
### `.eslintrc.cjs` -The `.eslintrc.cjs` file is used to configure ESLint. See [ESLint Docs](https://eslint.org/docs/latest/user-guide/configuring/configuration-files) for more information. +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` -The `next-env.d.ts` file ensures Next.js types are picked up by the TypeScript compiler. **You should not remove it or edit it as it can change at any time.** See [Next.js Docs](https://nextjs.org/docs/basic-features/typescript#existing-projects) for more information. +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` -The `next.config.mjs` file is used to configure Next.js. See [Next.js Docs](https://nextjs.org/docs/api-reference/next.config.js/introduction) for more information. Note: The .mjs extension is used to allow for ESM imports. +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` -The `postcss.config.cjs` file is used for Tailwind PostCSS usage. See [Tailwind PostCSS Docs](https://tailwindcss.com/docs/installation/using-postcss) for more information. +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` -The `prettier.config.mjs` file is used to configure Prettier to include the prettier-plugin-tailwindcss for formatting Tailwind CSS classes. See the [Tailwind CSS blog post](https://tailwindcss.com/blog/automatic-class-sorting-with-prettier) for more information. +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` -The `tsconfig.json` file is used to configure TypeScript. Some non-defaults, such as `strict mode`, have been enabled to ensure the best usage of TypeScript for Create T3 App and its libraries. See [TypeScript Docs](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html) or [TypeScript Usage](usage/typescript) for more information. +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` -The `drizzle.config.ts` file is used to configure drizzle kit. See [the documentation](https://orm.drizzle.team/kit-docs/config-reference) for more information. +File `drizzle.config.ts` digunakan untuk mengkonfigurasi drizzle kit. Lihat [dokumentasi](https://orm.drizzle.team/kit-docs/config-reference) untuk informasi lebih lanjut. -
\ No newline at end of file + From 5189592e3cd80cd91c074ab4d4c58e3174944f7a Mon Sep 17 00:00:00 2001 From: Imamuzzaki Abu Salam Date: Mon, 30 Oct 2023 09:22:02 +0700 Subject: [PATCH 10/13] docs: translare examples and faq to id --- www/src/pages/id/examples.mdx | 12 +++--- www/src/pages/id/faq.mdx | 74 +++++++++++++++++------------------ 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/www/src/pages/id/examples.mdx b/www/src/pages/id/examples.mdx index bc7e45fb62..eb6f37fa16 100644 --- a/www/src/pages/id/examples.mdx +++ b/www/src/pages/id/examples.mdx @@ -1,22 +1,22 @@ --- -title: Examples -description: Examples of different live apps +title: Contoh +description: Contoh aplikasi langsung yang berbeda layout: ../../layouts/docs.astro -lang: en +lang: id isMdx: true --- import Callout from "../../components/docs/callout.tsx"; import Form from "../../components/docs/exampleOptionForm.astro"; -You can try out different combinations of technologies that create-t3-app offers. +Anda dapat mencoba berbagai kombinasi teknologi yang ditawarkan oleh create-t3-app. - You cannot select `prisma` and `drizzle` at the same time. + Anda tidak dapat memilih `prisma` dan `drizzle` secara bersamaan. - Some features might not work unless you create an env file + 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 index 1271158411..28be2bbf19 100644 --- a/www/src/pages/id/faq.mdx +++ b/www/src/pages/id/faq.mdx @@ -1,20 +1,20 @@ --- -title: FAQ -description: Frequently asked questions about Create T3 App +title: Pertanyaan Umum +description: Pertanyaan yang Sering Diajukan tentang Create T3 App layout: ../../layouts/docs.astro -lang: en +lang: id isMdx: true --- import Callout from "../../components/docs/callout.tsx"; -Here are some commonly asked questions about Create T3 App. +Berikut adalah beberapa pertanyaan yang sering diajukan tentang Create T3 App. -## What's next? How do I make an app with this? +## Apa selanjutnya? Bagaimana cara membuat aplikasi dengan ini? -We try to keep this project as simple as possible, so you can start with just the scaffolding we set up for you, and add additional things later when they become necessary. +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. -If you are not familiar with the different technologies used in this project, please refer to the respective docs. If you still are in the wind, please join our [Discord](https://t3.gg/discord) and ask for help. +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) @@ -23,54 +23,54 @@ If you are not familiar with the different technologies used in this project, pl - [tRPC](https://trpc.io) - [Drizzle](https://orm.drizzle.team/docs/overview) -## How do I keep my app up to date? +## Bagaimana cara menjaga aplikasi saya tetap terbaru? -Create T3 App is a scaffolding tool, not a framework. This means that once you initialize an app, it's yours. There is no postinstall CLI tool similar to help you stay up to date. If you want to keep track of any improvements we make to the template, you could [enable notifications for releases](https://docs.github.com/en/account-and-profile/managing-subscriptions-and-notifications-on-github/setting-up-notifications/configuring-notifications#configuring-your-watch-settings-for-an-individual-repository) on our repository. That being said it is not really necessary to implement every change we make to the template in your app. +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. -## What learning resources are currently available? +## Apa sumber daya pembelajaran yang saat ini tersedia? -Although the resources listed below are some of the best that exist for the T3 Stack, the community (and [Theo](https://youtu.be/rzwaaWH0ksk?t=1436)) recommend that you just start using the stack and learn along the way by building with it. +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. -If you are considering Create T3 App, chances are you might have already used some of the parts of the stack. So why not just dive in head first and learn the other parts while you build something? +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? -Now, we realize this path doesn't work for everyone. So, if you feel like you've tried the recommendation and would still like some resources, or you just aren't confident doing it by yourself and/or feel overwhelmed by the stack, checkout these awesome tutorials on Create T3 App: +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: -### Articles +### Artikel -Some of these might be outdated. +Beberapa di antaranya mungkin sudah usang. -- [A first look at Create T3 App](https://dev.to/ajcwebdev/a-first-look-at-create-t3-app-1i8f) -- [Migrating your T3 App into a Turborepo](https://www.jumr.dev/blog/t3-turbo) -- [Integrating Stripe into your T3 App](https://blog.nickramkissoon.com/posts/integrate-stripe-t3) +- [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) -### Videos +### Video -- [T3 Stack Tutorial - FROM 0 TO PROD FOR $0 (Next.js, tRPC, TypeScript, Tailwind, Prisma & More)](https://www.youtube.com/watch?v=YkOSUVzOAA4) **(recommended)** -- [Jack Herrington - Build a Note Taking app with the T3 Stack](https://www.youtube.com/watch?v=J1gzN1SAhyM) -- [Build a Twitter Clone with the T3 Stack - tRPC, Next.js, Prisma, Tailwind & Zod](https://www.youtube.com/watch?v=nzJsYJPCc80) -- [Build a Blog With the T3 Stack - tRPC, TypeScript, Next.js, Prisma & Zod](https://www.youtube.com/watch?v=syEWlxVFUrY) -- [Build a Live Chat Application with the T3 Stack - TypeScript, Tailwind, tRPC](https://www.youtube.com/watch?v=dXRRY37MPuk) -- [The T3 Stack - How We Built It](https://www.youtube.com/watch?v=H-FXwnEjSsI) -- [An overview of the Create T3 App (Next, Typescript, Tailwind, tRPC, Next-Auth)](https://www.youtube.com/watch?v=VJH8dsPtbeU) +- [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) -## Why are there `.js` files in the project? +## Mengapa ada file `.js` dalam proyek? -As per [T3-Axiom #3](/en/introduction#typesafety-isnt-optional), we treat typesafety as a first class citizen. Unfortunately, not all frameworks and plugins support TypeScript which means some of the configuration files have to be `.js` files. +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`. -We try to emphasize that these files are JavaScript for a reason, by explicitly declaring each file's type (`cjs` or `mjs`) depending on what's supported by the library it is used by. Also, all the `js` files in this project are still typechecked using a checkJs option in the compiler (tsconfig). +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). -## I'm struggling to add i18n to my app. Is there any reference I can use? +## Saya kesulitan menambahkan i18n ke aplikasi saya. Apakah ada referensi yang bisa saya gunakan? -We have decided against including i18n by default in `create-t3-app` because it's a very opinionated topic and there are many ways to implement it. +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. -However, if you struggle to implement it and want to see a reference project, we have a [reference repo](https://github.com/juliusmarminge/t3-i18n) that shows how you can add i18n to a T3 App using [next-i18next](https://github.com/i18next/next-i18next). +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). -## Why are we using `/pages` and not `/app` from Next.js 13? +## Mengapa kita menggunakan `/pages` dan tidak `/app` dari Next.js 13? -As per [T3-Axiom #2](/en/introduction#bleed-responsibly), we love bleeding edge stuff but value stability, your entire router is hard to port, [not a great place to bleed](https://youtu.be/mnwUbtieOuI?t=1662). While `/app` is [a glimpse into the future](https://youtu.be/rnsC-12PVlM?t=818), it's not ready for production; The API is in beta and expected to have breaking changes. +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. - For a list of supported, planned, and worked on features in the `/app` dir, - visit the [beta Next.js - docs](https://beta.nextjs.org/docs/app-directory-roadmap#supported-and-planned-features). + 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). From f383e4a0a30a92010402fe8944a873208b8246ec Mon Sep 17 00:00:00 2001 From: Imamuzzaki Abu Salam Date: Mon, 30 Oct 2023 09:41:44 +0700 Subject: [PATCH 11/13] docs: translate the rest to id --- www/src/config.ts | 2 +- www/src/pages/id/deployment/docker.md | 82 +++++------ www/src/pages/id/deployment/index.astro | 2 +- www/src/pages/id/deployment/netlify.mdx | 61 ++++---- www/src/pages/id/deployment/vercel.md | 38 ++--- www/src/pages/id/usage/drizzle.mdx | 6 +- www/src/pages/id/usage/env-variables.mdx | 70 ++++----- www/src/pages/id/usage/first-steps.md | 56 ++++---- www/src/pages/id/usage/index.astro | 7 +- www/src/pages/id/usage/next-auth.mdx | 100 ++++++------- www/src/pages/id/usage/next-js.md | 40 +++--- www/src/pages/id/usage/prisma.md | 42 +++--- www/src/pages/id/usage/tailwind.md | 68 ++++----- www/src/pages/id/usage/trpc.md | 176 ++++++++++++----------- www/src/pages/id/usage/typescript.md | 42 +++--- 15 files changed, 400 insertions(+), 392 deletions(-) diff --git a/www/src/config.ts b/www/src/config.ts index 4eb8bd691b..8b64102ddf 100644 --- a/www/src/config.ts +++ b/www/src/config.ts @@ -436,7 +436,7 @@ export const SIDEBAR_HEADER_MAP: Record< id: { "Create T3 App": "Create T3 App", Usage: "Pemakaian", - Deployment: "Penyebaran", + Deployment: "Deployment", }, fr: { "Create T3 App": "Create T3 App", diff --git a/www/src/pages/id/deployment/docker.md b/www/src/pages/id/deployment/docker.md index f9941e0e2a..f2a20ae7a9 100644 --- a/www/src/pages/id/deployment/docker.md +++ b/www/src/pages/id/deployment/docker.md @@ -1,22 +1,22 @@ --- title: Docker -description: Deployment with Docker +description: Deployment dengan Docker layout: ../../../layouts/docs.astro -lang: en +lang: id --- -You can containerize this stack and deploy it as a single container using Docker, or as a part of a group of containers using docker-compose. See [`ajcwebdev/ct3a-docker`](https://github.com/ajcwebdev/ct3a-docker) for an example repo based on this doc. +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. -## Docker Project Configuration +## Konfigurasi Proyek Docker -Please note that Next.js requires a different process for build time (available in the frontend, prefixed by `NEXT_PUBLIC`) and runtime environment, server-side only, variables. In this demo we are using two variables, pay attention to their positions in the `Dockerfile`, command-line arguments, and `docker-compose.yml`: +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` (used by the server) -- `NEXT_PUBLIC_CLIENTVAR` (used by the client) +- `DATABASE_URL` (digunakan oleh server) +- `NEXT_PUBLIC_CLIENTVAR` (digunakan oleh client) -### 1. Next Configuration +### 1. Konfigurasi Next -In your [`next.config.mjs`](https://github.com/t3-oss/create-t3-app/blob/main/cli/template/base/next.config.mjs), add the `standalone` output-option configuration to [reduce image size by automatically leveraging output traces](https://nextjs.org/docs/advanced-features/output-file-tracing): +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({ @@ -26,11 +26,11 @@ export default defineNextConfig({ }); ``` -### 2. Create dockerignore file +### 2. Buat file .dockerignore
- Click here and include contents in .dockerignore: + Klik di sini dan sertakan konten dalam .dockerignore:
@@ -49,13 +49,13 @@ README.md
-### 3. Create Dockerfile +### 3. Buat Dockerfile -> Since we're not pulling the server environment variables into our container, the [environment schema validation](/en/usage/env-variables) will fail. To prevent this, we have to add a `SKIP_ENV_VALIDATION=1` flag to the build command so that the env-schemas aren't validated at build time. +> 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.
- Click here and include contents in Dockerfile: + Klik di sini dan sertakan konten dalam Dockerfile:
@@ -126,34 +126,36 @@ CMD ["node", "server.js"] ``` -> **_Notes_** +> **_Catatan_** > -> - _Emulation of `--platform=linux/amd64` may not be necessary after moving to Node 18._ -> - _See [`node:alpine`](https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine) to understand why `libc6-compat` might be needed._ -> - _Using Alpine 3.17 based images [can cause issues with Prisma](https://github.com/t3-oss/create-t3-app/issues/975). Setting `engineType = "binary"` solves the issue in Alpine 3.17, [but has an associated performance cost](https://www.prisma.io/docs/concepts/components/prisma-engines/query-engine#the-query-engine-at-runtime)._ -> - _Next.js collects [anonymous telemetry data about general usage](https://nextjs.org/telemetry). Uncomment the first instance of `ENV NEXT_TELEMETRY_DISABLED 1` to disable telemetry during the build. Uncomment the second instance to disable telemetry during runtime._ +> - _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._
-## Build and Run Image Locally +## Bangun dan Jalankan Gambar Secara Lokal -Build and run this image locally with the following commands: +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 + + ``` -Open [localhost:3000](http://localhost:3000/) to see your running application. +Buka [localhost:3000](http://localhost:3000/) untuk melihat aplikasi yang berjalan. ## Docker Compose -You can also use Docker Compose to build the image and run the container. +Anda juga dapat menggunakan Docker Compose untuk membangun gambar dan menjalankan kontainer.
- Follow steps 1-4 above, click here, and include contents in docker-compose.yml: + Ikuti langkah 1-4 di atas, klik di sini, dan sertakan konten dalam docker-compose.yml:
@@ -175,20 +177,20 @@ services: - DATABASE_URL=database_url_goes_here ``` -Run this using the `docker compose up` command: +Jalankan ini menggunakan perintah `docker compose up`: ```bash docker compose up ``` -Open [localhost:3000](http://localhost:3000/) to see your running application. +Buka [localhost:3000](http://localhost:3000/) untuk melihat aplikasi yang berjalan.
-## Deploy to Railway +## Deploy ke Railway -You can use a PaaS such as [Railway's](https://railway.app) automated [Dockerfile deployments](https://docs.railway.app/deploy/dockerfiles) to deploy your app. If you have the [Railway CLI installed](https://docs.railway.app/develop/cli#install) you can deploy your app with the following commands: +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 @@ -198,17 +200,17 @@ railway up railway open ``` -Go to "Variables" and include your `DATABASE_URL`. Then go to "Settings" and select "Generate Domain." To view a running example on Railway, visit [ct3a-docker.up.railway.app](https://ct3a-docker.up.railway.app/). +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/). -## Useful Resources +## Sumber Daya Berguna -| Resource | Link | -| ------------------------------------ | -------------------------------------------------------------------- | -| Dockerfile reference | https://docs.docker.com/engine/reference/builder/ | -| Compose file version 3 reference | https://docs.docker.com/compose/compose-file/compose-file-v3/ | -| Docker CLI reference | https://docs.docker.com/engine/reference/commandline/docker/ | -| Docker Compose CLI reference | https://docs.docker.com/compose/reference/ | -| Next.js Deployment with Docker Image | https://nextjs.org/docs/deployment#docker-image | -| Next.js in Docker | https://benmarte.com/blog/nextjs-in-docker/ | -| Next.js with Docker Example | https://github.com/vercel/next.js/tree/canary/examples/with-docker | -| Create Docker Image of a Next.js app | https://blog.tericcabrel.com/create-docker-image-nextjs-application/ | +| 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 index 22aec56d1d..40b21cb888 100644 --- a/www/src/pages/id/deployment/index.astro +++ b/www/src/pages/id/deployment/index.astro @@ -7,7 +7,7 @@ import Layout from "../../../layouts/docs.astro"; const frontmatter: Frontmatter = { title: "Deployment", layout: "docs", - description: "Learn how to deploy your T3 app to production.", + description: "Pelajari cara men-deploy aplikasi T3 Anda dalam produksi.", }; const lang = getLanguageFromURL(Astro.url.pathname); diff --git a/www/src/pages/id/deployment/netlify.mdx b/www/src/pages/id/deployment/netlify.mdx index a2fddd8c63..f39191491b 100644 --- a/www/src/pages/id/deployment/netlify.mdx +++ b/www/src/pages/id/deployment/netlify.mdx @@ -1,32 +1,31 @@ --- title: Netlify -description: Deploying to Netlify +description: Penyedia Deploy ke Netlify layout: ../../../layouts/docs.astro -lang: en +lang: id isMdx: true --- import Callout from "../../../components/docs/callout.tsx"; -Netlify is an alternative deployment provider in a similar vein to Vercel. See [`ajcwebdev/ct3a-netlify`](https://github.com/ajcwebdev/ct3a-netlify) for an example repo based on this doc. +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. -## Why Host on Netlify +## Mengapa Menggunakan Netlify -Conventional wisdom says Vercel has superior Next.js support because Vercel develops Next.js. They have a vested interest in ensuring the platform is tuned for optimal performance and DX with Next.js. For the majority of use cases this will be true and it won't make sense to deviate from the standard path. +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. -There's also a common sentiment that many Next.js features are only supported on Vercel. While it's true that new Next.js features will be tested and supported on Vercel at the time of release by default, it's also the case that other providers like Netlify will [quickly implement and release support](https://www.netlify.com/blog/deploy-nextjs-13/) for [stable Next.js features](https://docs.netlify.com/integrations/frameworks/next-js/overview/). +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/). -There are relative pros and cons for all deployment providers since no single host can have the best support for all use cases. For example, Netlify built their own [custom Next.js runtime](https://github.com/netlify/next-runtime) for Netlify's Edge Functions (which run on Deno Deploy) and [maintain unique middleware to access and modify HTTP responses](https://github.com/netlify/next-runtime#nextjs-middleware-on-netlify). +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). - To track the status of non-stable Next 13 features see [Using the Next 13 - `app` directory on - Netlify](https://github.com/netlify/next-runtime/discussions/1724). + 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). -## Project Configuration +## Konfigurasi Proyek -There are numerous ways to configure your build instructions including directly through the Netlify CLI or Netlify dashboard. While not required, it is advisable to create and include a [`netlify.toml`](https://docs.netlify.com/configure-builds/file-based-configuration/) file. This ensures forked and cloned versions of the project will be easier to reproducibly deploy. +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] @@ -34,60 +33,60 @@ There are numerous ways to configure your build instructions including directly publish = ".next" ``` -## Using the Netlify Dashboard +## Menggunakan Dashboard Netlify -1. Push your code to a GitHub repository and sign up for [Netlify](https://app.netlify.com/signup). After you've created an account, click on **Add new site** and then **Import an existing project**. +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**. -![New project on Netlify](/images/netlify-01-new-project.webp) +![Proyek baru di Netlify](/images/netlify-01-proyek-baru.webp) -2. Connect your Git provider. +2. Sambungkan penyedia Git Anda. -![Import repository](/images/netlify-02-connect-to-git-provider.webp) +![Impor repositori](/images/netlify-02-terhubung-ke-penyedia-git.webp) -3. Select your project's repository. +3. Pilih repositori proyek Anda. -![Select your project's repository](/images/netlify-03-pick-a-repository-from-github.webp) +![Pilih repositori proyek Anda](/images/netlify-03-pilih-repositori-dari-github.webp) -4. Netlify will detect if you have a `netlify.toml` file and automatically configure your build command and publish directory. +4. Netlify akan mendeteksi jika Anda memiliki file `netlify.toml` dan secara otomatis mengonfigurasi perintah pembangunan dan direktori penerbitan Anda. -![Nextjs build settings](/images/netlify-04-configure-build-settings.webp) +![Pengaturan build Next.js](/images/netlify-04-konfigurasi-pengaturan-build.webp) -5. Click **Show advanced** and then **New variable** to add your environment variables. +5. Klik **Tampilkan lanjutan** dan kemudian **Variabel baru** untuk menambahkan variabel lingkungan Anda. -![Add environment variables](/images/netlify-05-env-vars.webp) +![Tambahkan variabel lingkungan](/images/netlify-05-variabel-lingkungan.webp) -6. Click **Deploy site**, wait for the build to complete, and view your new site. +6. Klik **Deploy situs**, tunggu hingga proses pembangunan selesai, dan lihat situs baru Anda. -## Using the Netlify CLI +## Menggunakan Netlify CLI -To deploy from the command line you must first push your project to a GitHub repo and [install the Netlify CLI](https://docs.netlify.com/cli/get-started/). You can install `netlify-cli` as a project dependency or install it globally on your machine with the following command: +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 ``` -To test your project locally, run the [`ntl dev`](https://docs.netlify.com/cli/get-started/#run-a-local-development-environment) command and open [`localhost:8888`](http://localhost:8888/) to view your locally running Netlify app: +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 ``` -Run the [`ntl init`](https://docs.netlify.com/cli/get-started/#continuous-deployment) command to configure your project: +Jalankan perintah [`ntl init`](https://docs.netlify.com/cli/get-started/#continuous-deployment) untuk mengonfigurasi proyek Anda: ```bash ntl init ``` -Import your project's environment variables from your `.env` file with [`ntl env:import`](https://cli.netlify.com/commands/env#envimport): +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 your project with [`ntl deploy`](https://docs.netlify.com/cli/get-started/#manual-deploys). You'll need to pass the `--build` flag to run the build command before deployment and the `--prod` flag to deploy to your site's main URL: +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 ``` -To view a running example on Netlify, visit [ct3a.netlify.app](https://ct3a.netlify.app/). +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 index 40609cf229..d9a175bb4a 100644 --- a/www/src/pages/id/deployment/vercel.md +++ b/www/src/pages/id/deployment/vercel.md @@ -1,15 +1,15 @@ --- title: Vercel -description: Deploying to Vercel +description: Deploy ke Vercel layout: ../../../layouts/docs.astro -lang: en +lang: id --- -We recommend deploying your app to [Vercel](https://vercel.com/?utm_source=t3-oss&utm_campaign=oss). It makes it super easy to deploy Next.js apps. +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. -## Project Configuration +## Konfigurasi Proyek -Vercel will likely configure your build command and publish the directory automatically. However, you can also specify this information along with other configurations by creating a file called [`vercel.json`](https://vercel.com/docs/project-configuration) and including the following commands. **This is not required for most projects.** +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 { @@ -20,43 +20,43 @@ Vercel will likely configure your build command and publish the directory automa } ``` -## Using the Vercel Dashboard +## Menggunakan Dashboard Vercel -1. After pushing your code to a GitHub repository, sign up for [Vercel](https://vercel.com/?utm_source=t3-oss&utm_campaign=oss) with GitHub and click on **Add New Project**. +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**. -![New project on Vercel](/images/vercel-new-project.webp) +![Proyek baru di Vercel](/images/vercel-proyek-baru.webp) -2. Import the GitHub repository with your project. +2. Impor repositori GitHub dengan proyek Anda. -![Import repository](/images/vercel-import-project.webp) +![Impor repositori](/images/vercel-impor-proyek.webp) -3. Add your environment variables. +3. Tambahkan variabel lingkungan Anda. -![Add environment variables](/images/vercel-env-vars.webp) +![Tambahkan variabel lingkungan](/images/vercel-variabel-lingkungan.webp) -4. Click **Deploy**. Now whenever you push a change to your repository, Vercel will automatically redeploy your app! +4. Klik **Deploy**. Sekarang, setiap kali Anda melakukan perubahan pada repositori Anda, Vercel akan secara otomatis melakukan redeploy aplikasi Anda! -## Using the Vercel CLI +## Menggunakan Vercel CLI -To deploy from the command line you must first [install the Vercel CLI globally](https://vercel.com/docs/cli#installing-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 ``` -Run the [`vercel`](https://vercel.com/docs/cli/deploying-from-cli) command to deploy your project. +Jalankan perintah [`vercel`](https://vercel.com/docs/cli/deploying-from-cli) untuk melakukan deploy proyek Anda. ```bash vercel ``` -Include `--env DATABASE_URL=YOUR_DATABASE_URL_HERE` for environment variables like the database connection string. Use `--yes` if you want to skip the deployment questions and give the default answer for each. +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=YOUR_DATABASE_URL_HERE --yes +vercel --env DATABASE_URL=URL_KONEKSI_DATABASE_ANDA_DI_SINI --yes ``` -After the first deployment this command will deploy to a preview branch. You will need to include `--prod` to push changes directly to the live site for future deployments. +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/usage/drizzle.mdx b/www/src/pages/id/usage/drizzle.mdx index aefe547554..14102afa6f 100644 --- a/www/src/pages/id/usage/drizzle.mdx +++ b/www/src/pages/id/usage/drizzle.mdx @@ -1,14 +1,14 @@ --- title: Drizzle -description: Usage of Drizzle +description: Penggunaan Drizzle layout: ../../../layouts/docs.astro -lang: en +lang: id isMdx: true --- import Callout from "../../../components/docs/callout.tsx"; - The `drizzle` option is a new addition and no docs have yet been written. Contributions are welcome! + 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 index 888dbcab63..5043cdea8a 100644 --- a/www/src/pages/id/usage/env-variables.mdx +++ b/www/src/pages/id/usage/env-variables.mdx @@ -1,18 +1,18 @@ --- -title: Environment Variables -description: Getting started with Create T3 App +title: Variabel Lingkungan +description: Memulai dengan Create T3 App layout: ../../../layouts/docs.astro -lang: en +lang: id isMdx: true --- import Callout from "../../../components/docs/callout.tsx"; -Create T3 App uses its own package [@t3-oss/env-nextjs](https://env.t3.gg) along with [zod](https://zod.dev) under the hood for validating environment variables at runtime _and_ buildtime by providing a simple logic in `src/env.mjs`. +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; If you want to add a new environment variable, you must add a validator for it in `src/env.mjs`, and then add the KV-pair in `.env`_ +_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"; @@ -31,70 +31,68 @@ export const env = createEnv({ }); ``` -T3 Env uses the `createEnv` function to create the schema validate both client and server-side environment variables. +T3 Env menggunakan fungsi `createEnv` untuk membuat skema yang memvalidasi variabel lingkungan baik di sisi klien maupun sisi server. - For more information about how `createEnv` works internally, check out the [T3 - Env](https://env.t3.gg/docs/introduction) docs + Untuk informasi lebih lanjut tentang bagaimana `createEnv` bekerja secara internal, lihat [Dokumentasi T3 Env](https://env.t3.gg/docs/introduction) -## Using Environment Variables +## Menggunakan Variabel Lingkungan -When you want to use your environment variables, you can import them from the created `env.mjs` and use them as you would normally do. If you import this on the client and try accessing a server-side environment variable, you will get a runtime error. +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` is fully typesafe and provides autocompletion +// `env` sepenuhnya aman tipe dan memberikan autokomplet const dbUrl = env.DATABASE_URL; ``` ```ts:pages/index.tsx import { env } from "../env.mjs"; -// ❌ This will throw a runtime error +// ❌ Ini akan menyebabkan kesalahan saat runtime const dbUrl = env.DATABASE_URL; -// ✅ This is fine +// ✅ Ini baik-baik saja const wsKey = env.NEXT_PUBLIC_WS_KEY; ``` ## .env.example -Since the default `.env` file is not committed to version control, we have also included a `.env.example` file, in which you can optionally keep a copy of your `.env` file with any secrets removed. This is not required, but we recommend keeping the example up to date to make it as easy as possible for contributors to get started with their environment. +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. -Some frameworks and build tools, like Next.js, suggest that you store secrets in a `.env.local` file and commit `.env` files to your project. This is not recommended, as it could make it easy to accidentally commit secrets to your project. Instead, we recommend that you store secrets in `.env`, keep your `.env` file in your `.gitignore` and only commit `.env.example` files to your project. +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. -## Adding Environment Variables +## Menambahkan Variabel Lingkungan -To ensure your build never completes without the environment variables the project needs, you will need to add new environment variables in **two** locations: +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`: Enter your environment variable like you would normally do in a `.env` file, i.e. `KEY=VALUE` +📄 `.env`: Masukkan variabel lingkungan Anda seperti biasanya dalam file `.env`, yaitu `KEY=VALUE` -📄 `env.mjs`: Add the appropriate validation logic for the environment variables by defining a Zod schema inside `createEnv` for each one, e.g. `KEY: z.string()`. Besides that, make sure to destruct them in the `runtimeEnv` option, e.g.: `KEY: process.env.KEY` +📄 `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` - Why do I need to destructure the environment variable in the `runtimeEnv`? - This is due to how Next.js bundles environment variables in certain runtimes. - By destructuring it manually, you ensure that the variable will never be - stripped out from the bundle. + 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. -Optionally, you can also keep `.env.example` updated: +Opsionalnya, Anda juga dapat menjaga agar `.env.example` tetap terbaru: -📄 `.env.example`: Enter your environment variable, but be sure to not include the value if it is secret, i.e. `KEY=VALUE` or `KEY=` +📄 `.env.example`: Masukkan variabel lingkungan Anda, tetapi pastikan untuk tidak menyertakan nilai jika itu adalah rahasia, yaitu `KEY=VALUE` atau `KEY=` -### Example +### Contoh -_I want to add my Twitter API Token as a server-side environment variable_ +_Saya ingin menambahkan Token API Twitter saya sebagai variabel lingkungan sisi server_ -1. Add the environment variable to `.env`: +1. Tambahkan variabel lingkungan ke dalam `.env`: ``` TWITTER_API_TOKEN=1234567890 ``` -2. Add the environment variable to `env.mjs`: +2. Tambahkan variabel lingkungan ke dalam `env.mjs`: ```ts import { createEnv } from "@t3-oss/env-nextjs"; @@ -112,24 +110,24 @@ export const env = createEnv({ }); ``` -3. _Optional:_ Add the environment variable to `.env.example` and make sure not to include the secret in the `runtimeEnv` option +3. _Opsional:_ Tambahkan variabel lingkungan ke dalam `.env.example` dan pastikan untuk tidak menyertakan rahasia di opsi `runtimeEnv` ```bash TWITTER_API_TOKEN= ``` -## Type Coercion +## Konversi Tipe -All variables you add to `.env` will be imported as strings, even if their value is intended to represent a different type. If you want to use your environment variables as a different type at runtime, you can use Zod's `coerce` to convert the string to the type you want. It will throw if the coercion fails. +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. -Add the variables to your `.env`: +Tambahkan variabel ke dalam `.env` Anda: ``` SOME_NUMBER=123 SOME_BOOLEAN=true ``` -Then, validate them in `env.mjs`: +Kemudian, validasi dalam `env.mjs`: ```ts import { createEnv } from "@t3-oss/env-nextjs"; @@ -138,6 +136,8 @@ import { z } from "zod"; export const env = createEnv({ server: { SOME_NUMBER: z.coerce.number(), + + SOME_BOOLEAN: z.coerce.boolean(), }, // ... @@ -146,4 +146,4 @@ export const env = createEnv({ 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 index 776f3ce8ff..a614c34081 100644 --- a/www/src/pages/id/usage/first-steps.md +++ b/www/src/pages/id/usage/first-steps.md @@ -1,50 +1,50 @@ --- -title: First Steps -description: Getting started with your new T3 App +title: Langkah Pertama +description: Memulai dengan Aplikasi T3 Baru Anda layout: ../../../layouts/docs.astro -lang: en +lang: id --- -You just scaffolded a new T3 App and are ready to go. Here is the bare minimum to get your app working. +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 -If your app includes Prisma, make sure to run `npx prisma db push` from the root directory of your app. This command will sync your Prisma schema with your database and will generate the TypeScript types for the Prisma Client based on your schema. Note that you need to [restart the TypeScript server](https://tinytip.co/tips/vscode-restart-ts/) after doing this so that it can detect the generated types. +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 -If your app includes Drizzle, check the `.env` file for instructions on how to construct your `DATABASE_URL` env variable. Once your env file is ready, run `pnpm db:push` (or the equivalent for other package managers) to push your schema. +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. -## Authentication +## Otentikasi -If your app includes NextAuth.js, we get you started with the `DiscordProvider`. This is one of the simplest providers that NextAuth.js offers, but it still requires a bit of initial setup on your part. +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. -Of course, if you prefer to use a different auth provider, you can also use one of the [many providers](https://next-auth.js.org/providers/) that NextAuth.js offers. +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. You will need a Discord account, so register one if you haven't already. -2. Navigate to https://discord.com/developers/applications and click "New Application" in the top right corner. Give your application a name and agree to the Terms of Service. -3. Once your application has been created, navigate to "Settings → OAuth2 → General". -4. Copy the "Client ID" and add it to your `.env` as `DISCORD_CLIENT_ID`. -5. Click "Reset Secret", copy the new secret, and add it to your `.env` as `DISCORD_CLIENT_SECRET`. -6. Click "Add Redirect" and type in `http://localhost:3000/api/auth/callback/discord`. - - For production deployment, follow the previous steps to create another Discord Application, but this time replace `http://localhost:3000` with the URL that you are deploying to. -7. Save Changes. -8. Set the `NEXTAUTH_SECRET` in `.env`. In development any string will work, for production see the note in `.env` on generating a secure secret. +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. -You should now be able to log in. +Anda sekarang seharusnya dapat masuk. -## Editor Setup +## Pengaturan Editor -The following extensions are recommended for an optimal developer experience. The links below provide editor specific plugin support. +Berikut adalah ekstensi yang direkomendasikan untuk pengalaman pengembangan yang optimal. Tautan di bawah ini menyediakan dukungan plugin yang spesifik untuk editor. -- [Prisma Extension](https://www.prisma.io/docs/guides/development-environment/editor-setup) -- [Tailwind CSS IntelliSense Extension](https://tailwindcss.com/docs/editor-setup) -- [Prettier Extension](https://prettier.io/docs/en/editors.html) +- [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) -## Next Steps +## Langkah Selanjutnya -- If your app includes tRPC, check out `src/pages/index.tsx` and `src/server/api/routers/post.ts` to see how tRPC queries work. -- Have a look around the Create T3 App docs, as well as the docs of the packages that your app includes. -- Join our [Discord](https://t3.gg/discord) and give us a star on [GitHub](https://github.com/t3-oss/create-t3-app)! :) +- 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 index 4c31ec7bf1..d984789d84 100644 --- a/www/src/pages/id/usage/index.astro +++ b/www/src/pages/id/usage/index.astro @@ -5,13 +5,14 @@ import { getLanguageFromURL } from "../../../languages"; import Layout from "../../../layouts/docs.astro"; const frontmatter: Frontmatter = { - title: "Usage", + title: "Pemakaian", layout: "docs", - description: "Learn how to use the different technology from the T3 Stack.", + // 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 sidebarEntries = SIDEBAR[lang]["Pemakaian"]!; 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 index cb0830caf5..0e00d68725 100644 --- a/www/src/pages/id/usage/next-auth.mdx +++ b/www/src/pages/id/usage/next-auth.mdx @@ -1,18 +1,18 @@ --- title: NextAuth.js -description: Usage of NextAuth.js +description: Penggunaan NextAuth.js layout: ../../../layouts/docs.astro -lang: en +lang: id isMdx: true --- import Callout from "../../../components/docs/callout.tsx"; -When you want an authentication system in your Next.js application, NextAuth.js is an excellent solution to bring in the complexity of security without the hassle of having to build it yourself. It comes with an extensive list of providers to quickly add OAuth authentication and provides adapters for many databases and ORMs. +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. -## Context Provider +## Penyedia Konteks -In your app's entrypoint, you'll see that your application is wrapped in a [SessionProvider](https://next-auth.js.org/getting-started/client#sessionprovider): +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 @@ -20,7 +20,7 @@ In your app's entrypoint, you'll see that your application is wrapped in a [Sess ``` -This context provider allows your application to access the session data from anywhere in your application, without having to pass it down as props: +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"; @@ -29,17 +29,17 @@ const User = () => { const { data: session } = useSession(); if (!session) { - // Handle unauthenticated state, e.g. render a SignIn component + // Tangani kondisi belum terotentikasi, misalnya render komponen SignIn return ; } - return

Welcome {session.user.name}!

; + return

Selamat datang {session.user.name}!

; }; ``` -## Retrieving session server-side +## Mengambil Sesi di Sisi Server -Sometimes you might want to request the session on the server. To do so, prefetch the session using the `getServerAuthSession` helper function that `create-t3-app` provides, and pass it down to the client using `getServerSideProps`: +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"; @@ -54,15 +54,15 @@ export const getServerSideProps: GetServerSideProps = async (ctx) => { const User = () => { const { data: session } = useSession(); - // NOTE: `session` wont have a loading state since it's already prefetched on the server + // CATATAN: `session` tidak akan memiliki status loading karena sudah diambil di sisi server ... } ``` -## Inclusion of `user.id` on the Session +## Penyertakan `user.id` pada Sesi -Create T3 App is configured to utilise the [session callback](https://next-auth.js.org/configuration/callbacks#session-callback) in the NextAuth.js config to include the user's ID within the `session` object. +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: { @@ -75,7 +75,7 @@ callbacks: { }, ``` -This is coupled with a type declaration file to make sure the `user.id` is typed when accessed on the `session` object. Read more about [`Module Augmentation`](https://next-auth.js.org/getting-started/typescript#module-augmentation) on NextAuth.js's docs. +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"; @@ -89,15 +89,15 @@ declare module "next-auth" { } ``` -The same pattern can be used to add any other data to the `session` object, such as a `role` field, but **should not be misused to store sensitive data** on the client. +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. -## Usage with tRPC +## Penggunaan dengan tRPC -When using NextAuth.js with tRPC, you can create reusable, protected procedures using [middleware](https://trpc.io/docs/v10/middlewares). This allows you to create procedures that can only be accessed by authenticated users. `create-t3-app` sets all of this up for you, allowing you to easily access the session object within authenticated procedures. +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. -This is done in a two step process: +Ini dilakukan dalam dua langkah: -1. Grab the session from the request headers using the [`getServerSession`](https://next-auth.js.org/configuration/nextjs#getServerSession) function. The advantage of using `getServerSession` instead of the regular `getSession` is that it's a server-side only function and doesn't trigger unnecessary fetch calls. `create-t3-app` creates a helper function that abstracts this peculiar API away so that you don't need to import both your NextAuth.js options as well as the `getServerSession` function every time you need to access the session. +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: { @@ -108,7 +108,7 @@ export const getServerAuthSession = (ctx: { }; ``` -Using this helper function, we can grab the session and pass it through to the tRPC context: +Dengan menggunakan fungsi bantuan ini, kita dapat mengambil sesi dan meneruskannya ke konteks tRPC: ```ts:server/api/trpc.ts import { getServerAuthSession } from "../auth"; @@ -122,7 +122,7 @@ export const createContext = async (opts: CreateNextContextOptions) => { }; ``` -2. Create a tRPC middleware that checks if the user is authenticated. We then use the middleware in a `protectedProcedure`. Any caller to these procedures must be authenticated, or else an error will be thrown which can be appropriately handled by the client. +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 }) => { @@ -131,7 +131,7 @@ const isAuthed = t.middleware(({ ctx, next }) => { } return next({ ctx: { - // infers the `session` as non-nullable + // memastikan bahwa `session` tidak dapat bernilai null session: { ...ctx.session, user: ctx.session.user }, }, }); @@ -140,14 +140,16 @@ const isAuthed = t.middleware(({ ctx, next }) => { export const protectedProcedure = t.procedure.use(isAuthed); ``` -The session object is a light, minimal representation of the user and only contains a few fields. When using the `protectedProcedures`, you have access to the user's id which can be used to fetch more data from the database. +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, + id: ctx + +.session.user.id, }, }); return user; @@ -155,15 +157,15 @@ const userRouter = router({ }); ``` -## Usage with Prisma +## Penggunaan dengan Prisma -Getting NextAuth.js to work with Prisma requires a lot of [initial setup](https://authjs.dev/reference/adapter/prisma/). `create-t3-app` handles all of this for you, and if you select both Prisma and NextAuth.js, you'll get a fully working authentication system with all the required models preconfigured. We ship your scaffolded app with a preconfigured Discord OAuth provider, which we chose because it is one of the easiest to get started with - just provide your tokens in the `.env` and you're good to go. However, you can easily add more providers by following the [NextAuth.js docs](https://next-auth.js.org/providers/). Note that certain providers require extra fields to be added to certain models. We recommend you read the documentation for the provider you would like to use to make sure you have all the required fields. +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. -### Adding new fields to your models +### Menambahkan Bidang Baru ke Model Anda -When adding new fields to any of the `User`, `Account`, `Session`, or `VerificationToken` models (most likely you'd only need to modify the `User` model), you need to keep in mind that the [Prisma adapter](https://next-auth.js.org/adapters/prisma) automatically creates fields on these models when new users sign up and log in. Therefore, when adding new fields to these models, you must provide default values for them, since the adapter is not aware of these fields. +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. -If for example, you'd like to add a `role` to the `User` model, you would need to provide a default value to the `role` field. This is done by adding a `@default` value to the `role` field in the `User` model: +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 { @@ -177,17 +179,17 @@ If for example, you'd like to add a `role` to the `User` model, you would need t } ``` -## Usage with Next.js middleware +## Penggunaan dengan Middleware Next.js -Usage of NextAuth.js with Next.js middleware [requires the use of the JWT session strategy](https://next-auth.js.org/configuration/nextjs#caveats) for authentication. This is because the middleware is only able to access the session cookie if it is a JWT. By default, Create T3 App is configured to use the **default** database strategy, in combination with Prisma as the database adapter. +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. - Using database sessions is the recommended approach and you should read up on JWTs before switching to the JWT session strategy to avoid any security issues. + 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. -After switching to the JWT session strategy. Make sure to update the `session` callback in `src/server/auth.ts`. -The `user` object will be `undefined`. Instead, retrieve the user's ID from the `token` object. -I.e.: +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 = { @@ -208,21 +210,21 @@ I.e.: }; ``` -## Setting up the default DiscordProvider +## Menyiapkan Default DiscordProvider -1. Head to [the Applications section in the Discord Developer Portal](https://discord.com/developers/applications), and click on "New Application" -2. In the settings menu, go to "OAuth2 => General" +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" -- Copy the Client ID and paste it in `DISCORD_CLIENT_ID` in `.env`. -- Under Client Secret, click "Reset Secret" and copy that string to `DISCORD_CLIENT_SECRET` in `.env`. Be careful as you won't be able to see this secret again, and resetting it will cause the existing one to expire. -- Click "Add Redirect" and paste in `/api/auth/callback/discord` (example for local development: http://localhost:3000/api/auth/callback/discord) -- Save your changes -- It is possible, but not recommended, to use the same Discord Application for both development and production. You could also consider [Mocking the Provider](https://github.com/trpc/trpc/blob/main/examples/next-prisma-websockets-starter/src/pages/api/auth/%5B...nextauth%5D.ts) during development. +- 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. -## Useful Resources +## Sumber Daya Berguna -| Resource | Link | -| --------------------------------- | --------------------------------------- | -| NextAuth.js Docs | https://next-auth.js.org/ | -| NextAuth.js GitHub | https://github.com/nextauthjs/next-auth | -| tRPC Kitchen Sink - with NextAuth | https://kitchen-sink.trpc.io/next-auth | +| 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 index 77bf718134..c32fba417c 100644 --- a/www/src/pages/id/usage/next-js.md +++ b/www/src/pages/id/usage/next-js.md @@ -1,37 +1,37 @@ --- title: Next.js -description: Usage of Next.js +description: Penggunaan Next.js layout: ../../../layouts/docs.astro -lang: en +lang: id --- -Next.js is a backend framework for your React applications. +Next.js adalah framework backend untuk aplikasi React Anda.
- +
-Check out [Theo's Next.js Conf talk](https://www.youtube.com/watch?v=W4UhNo3HAMw) to get a better understanding of what Next.js is and how it works.

+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.

-## Why should I use it? +## Mengapa Harus Menggunakannya? -We love React. It has made UI development accessible in ways we never imagined before. It also can lead developers down some rough paths. Next.js offers a lightly opinionated, heavily optimized approach to creating applications using React. From routing to API definitions to image rendering, we trust Next.js to lead developers towards good decisions. +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. -Pairing Next.js with [Vercel](https://vercel.com/) makes developing and deploying web apps easier than ever before. Their extremely generous free-tier and super intuitive interface provides a point and click solution to deploy your site (We ❤️ Vercel) +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) -## Get Static/Server Props +## Dapatkan Static/Server Props -A key feature of Next.js is its data fetching capabilities. We highly recommend reading through the [official documentation](https://nextjs.org/docs/basic-features/data-fetching) to understand how to use each method and how they differ. `getServerSideProps` is generally discouraged unless there is a good reason for it, due to the fact that it is a blocking call and will slow down your site. [Incremental Static Regeneration](https://nextjs.org/docs/basic-features/data-fetching/incremental-static-regeneration) is a great alternative to `getServerSideProps` when the data is dynamic and can be fetched incrementally. +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. -If you need to use this feature anyway, check these links out: [Advanced tRPC - Callers, functions, and gSSP](https://www.youtube.com/watch?v=G2ZzmgShHgQ) and [SSG-Helpers](https://trpc.io/docs/v9/ssg-helpers) +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) -## Useful Resources +## Sumber Daya Berguna -| Resource | Link | -| ------------------------------ | ---------------------------------- | -| Next.js Documentation | https://nextjs.org/docs | -| Next.js GitHub | https://github.com/vercel/next.js | -| Next.js Blog | https://nextjs.org/blog | -| Next.js Discord | https://nextjs.org/discord | -| Next.js Twitter | https://twitter.com/nextjs | -| Vercel/Next.js YouTube Channel | https://www.youtube.com/c/VercelHQ | +| 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 index 7dead0698e..61f989c689 100644 --- a/www/src/pages/id/usage/prisma.md +++ b/www/src/pages/id/usage/prisma.md @@ -1,31 +1,31 @@ --- title: Prisma -description: Usage of Prisma +description: Penggunaan Prisma layout: ../../../layouts/docs.astro -lang: en +lang: id --- -Prisma is an ORM for TypeScript, that allows you to define your database schema and models in a `schema.prisma` file, and then generate a type-safe client that can be used to interact with your database from your backend. +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 -Located at `src/server/db.ts`, the Prisma Client is instantiated as a global variable (as recommended as [best practice](https://www.prisma.io/docs/guides/database/troubleshooting-orm/help-articles/nextjs-prisma-client-dev-practices#problem) by the team at Prisma) and exported to be used in your API routes. We include the Prisma Client in [Context](/en/usage/trpc#-serverapitrpcts) by default and recommend using this instead of importing it separately in each file. +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. -## Schema +## Skema -You will find the Prisma schema file at `/prisma/schema.prisma`. This file is where you define your database schema and models, and is used when generating the Prisma Client. +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. -### With NextAuth.js +### Dengan NextAuth.js -When you select NextAuth.js in combination with Prisma, the schema file is generated and set up for you with the recommended values for the `User`, `Session`, `Account`, and `VerificationToken` models, as per the [NextAuth.js documentation](https://next-auth.js.org/adapters/prisma). +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). -## Default Database +## Basis Data Default -The default database is an SQLite database, which is great for development and quickly spinning up a proof-of-concept but is not recommended for production. You can change the database to use by changing the `provider` in the `datasource` block to either `postgresql` or `mysql`, and then updating the connection string within environment variables to point to your database. +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. -## Seeding your Database +## Menyemaikan Basis Data Anda -[Seeding your database](https://www.prisma.io/docs/guides/database/seed-database) is a great way to quickly populate your database with test data to help you get started. In order to setup seeding, you will need to create a `seed.ts` file in the `/prisma` directory, and then add a `seed` script to your `package.json` file. You'll also need some TypeScript runner that can execute the seed-script. We recommend [tsx](https://github.com/esbuild-kit/tsx), which is a very performant TypeScript runner that uses esbuild and doesn't require any ESM configuration, but `ts-node` or other runners will work as well. +[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 { @@ -65,14 +65,14 @@ main() }); ``` -Then, just run `pnpm db-seed` (or `npm`/`yarn`) to seed your database. +Kemudian, cukup jalankan `pnpm db-seed` (atau `npm`/`yarn`) untuk menyemai basis data Anda. -## Useful Resources +## Sumber Daya Berguna -| Resource | Link | -| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | -| Prisma Docs | https://www.prisma.io/docs/ | -| Prisma GitHub | https://github.com/prisma/prisma | -| Prisma Migrate Playground | https://playground.prisma.io/guides | -| NextAuth.JS Prisma Adapter | https://next-auth.js.org/adapters/prisma | -| Planetscale Connection Guide | https://www.prisma.io/docs/getting-started/setup-prisma/add-to-existing-project/relational-databases/connect-your-database-typescript-planetscale | +| 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 index bdb355a4b0..29e1bfd6c9 100644 --- a/www/src/pages/id/usage/tailwind.md +++ b/www/src/pages/id/usage/tailwind.md @@ -1,19 +1,19 @@ --- title: Tailwind CSS -description: Usage of Tailwind CSS +description: Penggunaan Tailwind CSS layout: ../../../layouts/docs.astro -lang: en +lang: id --- -## What is Tailwind CSS? +## Apa itu Tailwind CSS? -Tailwind CSS is a tiny, [utility first](https://tailwindcss.com/docs/utility-first) CSS framework for building custom designs, without the context switching that regular CSS requires. It is purely a CSS framework and does not provide any pre-built components or logic, and provides [a very different set of benefits](https://www.youtube.com/watch?v=CQuTF-bkOgc) compared to a component library like Material UI. +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. -It makes CSS incredibly easy and quick to write, as shown by the following example: +Tailwind CSS membuat penulisan CSS menjadi sangat mudah dan cepat, seperti yang ditunjukkan oleh contoh berikut: -Old CSS: +CSS Lama: -1. Write CSS, often in a separate file +1. Tulis CSS, seringkali di file terpisah ```css .my-class { @@ -28,21 +28,21 @@ Old CSS: } ``` -2. Import CSS into your component +2. Impor CSS ke dalam komponen Anda ```jsx import "./my-class.css"; ``` -3. Add the class to your HTML +3. Tambahkan kelas ke HTML Anda ```html
...
``` -Equivalent in Tailwind: +Setara dalam Tailwind: -1. Just write classes in your HTML +1. Hanya menulis kelas dalam HTML Anda ```html
``` -When used together with React Components, it is extremely powerful for quickly building UIs. +Ketika digunakan bersama dengan Komponen React, Tailwind CSS sangat kuat untuk dengan cepat membangun UI. -Tailwind CSS has a beautiful built-in design system, that comes out of the box with a carefully chosen color palette, sizing patterns for styles such as width/height and padding/margin for a uniform design, as well as media breakpoints for creating responsive layouts. This design system can be customized and extended to create the exact toolbox of styles that your project needs. +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 better known as [mewtru](https://twitter.com/trunarla) gave an amazing talk on [building a design system using Tailwind CSS](https://www.youtube.com/watch?v=T-Zv73yZ_QI). +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). -## Usage +## Penggunaan -Make sure you have editor plugins for Tailwind installed to improve your experience writing Tailwind. +Pastikan Anda telah menginstal plugin editor untuk Tailwind untuk meningkatkan pengalaman menulis Tailwind. -### Extensions and Plugins +### Ekstensi dan Plugin -- [VSCode Extension](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss) -- [JetBrains Integration](https://www.jetbrains.com/help/webstorm/tailwind-css.html#ws_css_tailwind_install) +- [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) -### Formatting +### Pemformatan -Tailwind CSS classes can easily get a bit messy, so a formatter for the classes is a must have. [Tailwind CSS Prettier Plugin](https://github.com/tailwindlabs/prettier-plugin-tailwindcss) sorts the classes in the [recommended order](https://tailwindcss.com/blog/automatic-class-sorting-with-prettier#how-classes-are-sorted) so that the classes match the outputted css bundle. When selecting Tailwind in the CLI, we will install and configure this for you. +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. -### Conditionally Applying Classes +### Penggunaan Kelas Secara Kondisional -Conditionally adding classes using ternaries can get very messy and hard to read. These packages help in organizing your classes when using some conditional logic. +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) -## Useful Resources - -| Resource | Link | -| ---------------------------- | -------------------------------------------------------- | -| Tailwind Docs | https://tailwindcss.com/docs/editor-setup/ | -| Tailwind Cheat Sheet | https://nerdcave.com/tailwind-cheat-sheet/ | -| awesome-tailwindcss | https://github.com/aniftyco/awesome-tailwindcss/ | -| Tailwind Community | https://github.com/tailwindlabs/tailwindcss/discussions/ | -| Tailwind Discord Server | https://tailwindcss.com/discord/ | -| TailwindLabs Youtube Channel | https://www.youtube.com/tailwindlabs/ | -| Tailwind Playground | https://play.tailwindcss.com/ | +## 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 index 789311d17f..efb9659adb 100644 --- a/www/src/pages/id/usage/trpc.md +++ b/www/src/pages/id/usage/trpc.md @@ -1,16 +1,16 @@ --- title: tRPC -description: Usage of tRPC +description: Penggunaan tRPC layout: ../../../layouts/docs.astro -lang: en +lang: id --- -tRPC allows us to write end-to-end typesafe APIs without any code generation or runtime bloat. It uses TypeScript's great inference to infer your API router's type definitions and lets you call your API procedures from your frontend with full typesafety and autocompletion. When using tRPC, your frontend and backend feel closer together than ever before, allowing for an outstanding developer experience. +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.

- I built tRPC to allow people to move faster by removing the need of a traditional API-layer, while still having confidence that our apps won't break as we rapidly iterate. + 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.

@@ -20,7 +20,7 @@ tRPC allows us to write end-to-end typesafe APIs without any code generation or src="https://avatars.githubusercontent.com/u/459267?v=4" />
- Alex - creator of tRPC + Alex - pencipta tRPC
-## How do I use tRPC? +## Bagaimana Cara Menggunakan tRPC?
- +
-tRPC contributor [trashh_dev](https://twitter.com/trashh_dev) made [a killer talk at Next.js Conf](https://www.youtube.com/watch?v=2LYM8gf184U) about tRPC. We highly recommend you watch it if you haven't already. +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. -With tRPC, you write TypeScript functions on your backend, and then call them from your frontend. A simple tRPC procedure could look like this: +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({ @@ -55,11 +55,11 @@ const userRouter = createTRPCRouter({ }); ``` -This is a tRPC procedure (equivalent to a route handler in a traditional backend) that first validates the input using Zod (which is the same validation library that we use for [environment variables](./env-variables)) - in this case, it's making sure that the input is a string. If the input is not a string it will send an informative error instead. +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. -After the input, we chain a resolver function which can be either a [query](https://trpc.io/docs/v10/react-queries), [mutation](https://trpc.io/docs/v10/react-mutations), or a [subscription](https://trpc.io/docs/v10/subscriptions). In our example, the resolver calls our database using our [prisma](./prisma) client and returns the user whose `id` matches the one we passed in. +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. -You define your procedures in `routers` which represent a collection of related procedures with a shared namespace. You may have one router for `users`, one for `posts`, and another one for `messages`. These routers can then be merged into a single, centralized `appRouter`: +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({ @@ -71,9 +71,9 @@ const appRouter = createTRPCRouter({ export type AppRouter = typeof appRouter; ``` -Notice that we only need to export our router's type definitions, which means we are never importing any server code on our client. +Perhatikan bahwa kami hanya perlu mengekspor definisi tipe router kami, yang berarti kami tidak pernah mengimpor kode server apa pun di client kami. -Now let's call the procedure on our frontend. tRPC provides a wrapper for `@tanstack/react-query` which lets you utilize the full power of the hooks they provide, but with the added benefit of having your API calls typed and inferred. We can call our procedures from our frontend like this: +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"; @@ -91,13 +91,13 @@ const UserPage = () => { }; ``` -You'll immediately notice how good the autocompletion and typesafety is. As soon as you write `api.`, your routers will show up in autocomplete, and when you select a router, its procedures will show up as well. You'll also get a TypeScript error if your input doesn't match the validator that you defined on the backend. +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. -## Inferring errors +## Menginfer Error -By default, `create-t3-app` sets up an [error formatter](https://trpc.io/docs/error-formatting) that lets you infer your Zod Errors if you get validation errors on the backend. +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. -Example usage: +Contoh penggunaan: ```tsx function MyComponent() { @@ -110,8 +110,10 @@ function MyComponent() { mutate({ title: formData.get('title') }); }}> - {error?.data?.zodError?.fieldErrors.title && ( - {/** `mutate` returned with an error on the `title` */} + {error?.data?.zodError?.field + +Errors.title && ( + {/** `mutate` mengembalikan error di `title` */} {error.data.zodError.fieldErrors.title} @@ -123,57 +125,57 @@ function MyComponent() { } ``` -## Files +## Berkas -tRPC requires quite a lot of boilerplate that `create-t3-app` sets up for you. Let's go over the files that are generated: +tRPC memerlukan cukup banyak boilerplate yang disiapkan oleh `create-t3-app`. Mari kita bahas berkas-berkas yang dihasilkan: ### 📄 `pages/api/trpc/[trpc].ts` -This is the entry point for your API and exposes the tRPC router. Normally, you won't touch this file very much, but if you need to, for example, enable CORS middleware or similar, it's useful to know that the exported `createNextApiHandler` is a [Next.js API handler](https://nextjs.org/docs/api-routes/introduction) which takes a [request](https://developer.mozilla.org/en-US/docs/Web/API/Request) and [response](https://developer.mozilla.org/en-US/docs/Web/API/Response) object. This means that you can wrap the `createNextApiHandler` in any middleware you want. See below for an [example snippet](#enabling-cors) of adding CORS. +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` -This file is split up in two parts, context creation and tRPC initialization: +File ini dibagi menjadi dua bagian, pembuatan konteks dan inisialisasi tRPC: -1. We define the context that is passed to your tRPC procedures. Context is data that all of your tRPC procedures will have access to, and is a great place to put things like database connections, authentication information, etc. In create-t3-app we use two functions, to enable using a subset of the context when we do not have access to the request object. +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`: This is where you define context which doesn't depend on the request, e.g. your database connection. You can use this function for [integration testing](#sample-integration-test) or [ssg-helpers](https://trpc.io/docs/v10/ssg-helpers) where you don't have a request object. +- `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`: This is where you define context which depends on the request, e.g. the user's session. You request the session using the `opts.req` object, and then pass the session down to the `createInnerTRPCContext` function to create the final context. +- `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. We initialize tRPC and define reusable [procedures](https://trpc.io/docs/v10/procedures) and [middlewares](https://trpc.io/docs/v10/middlewares). By convention, you shouldn't export the entire `t`-object but instead, create reusable procedures and middlewares and export those. +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. -You'll notice we use `superjson` as [data transformer](https://trpc.io/docs/v10/data-transformers). This makes it so that your data types are preserved when they reach the client, so if you for example send a `Date` object, the client will return a `Date` and not a string which is the case for most APIs. +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` -This is where you define the routes and procedures of your API. By convention, you [create separate routers](https://trpc.io/docs/v10/router) for related procedures. +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` -Here we [merge](https://trpc.io/docs/v10/merging-routers) all the sub-routers defined in `routers/**` into a single app router. +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` -This is the frontend entry point for tRPC. This is where you'll import the router's **type definition** and create your tRPC client along with the react-query hooks. Since we enabled `superjson` as our data transformer on the backend, we need to enable it on the frontend as well. This is because the serialized data from the backend is deserialized on the frontend. +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. -You'll define your tRPC [links](https://trpc.io/docs/v10/links) here, which determines the request flow from the client to the server. We use the "default" [`httpBatchLink`](https://trpc.io/docs/v10/links/httpBatchLink) which enables [request batching](https://cloud.google.com/compute/docs/api/how-tos/batch), as well as a [`loggerLink`](https://trpc.io/docs/v10/links/loggerLink) which outputs useful request logs during development. +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. -Lastly, we export a [helper type](https://trpc.io/docs/v10/infer-types#additional-dx-helper-type) which you can use to infer your types on the frontend. +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.
- +
-Create T3 App contributor [Christopher Ehrlich](https://twitter.com/ccccjjjjeeee) made [a video about data flows in tRPC](https://www.youtube.com/watch?v=x4mu-jOiA0Q). This video is recommended if you have used tRPC but still feel a bit unclear about how it works. +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. -## How do I call my API externally? +## Bagaimana Cara Memanggil API Saya Secara Eksternal? -With regular APIs, you can call your endpoints using any HTTP client such as `curl`, `Postman`, `fetch` or straight from your browser. With tRPC, it's a bit different. If you want to call your procedures without the tRPC client, there are two recommended ways to do it: +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: -### Expose a single procedure externally +### Mengekspos Satu Prosedur Secara Eksternal -If you want to expose a single procedure externally, you're looking for [server side calls](https://trpc.io/docs/v10/server-side-calls). That would allow you to create a normal Next.js API endpoint, but reuse the resolver part of your tRPC procedure. +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"; @@ -181,7 +183,7 @@ import { appRouter } from "../../../server/api/root"; import { createTRPCContext } from "../../../server/api/trpc"; const userByIdHandler = async (req: NextApiRequest, res: NextApiResponse) => { - // Create context and caller + // Buat konteks dan pemanggil const ctx = await createTRPCContext({ req, res }); const caller = appRouter.createCaller(ctx); try { @@ -190,30 +192,30 @@ const userByIdHandler = async (req: NextApiRequest, res: NextApiResponse) => { res.status(200).json(user); } catch (cause) { if (cause instanceof TRPCError) { - // An error from tRPC occured + // Terjadi kesalahan dari tRPC const httpCode = getHTTPStatusCodeFromError(cause); return res.status(httpCode).json(cause); } - // Another error occured + // Terjadi kesalahan lainnya console.error(cause); - res.status(500).json({ message: "Internal server error" }); + res.status(500).json({ message: "Kesalahan server internal" }); } }; export default userByIdHandler; ``` -### Exposing every procedure as a REST endpoint +### Mengekspos Setiap Prosedur Sebagai Endpoint REST -If you want to expose every single procedure externally, checkout the community built plugin [trpc-openapi](https://github.com/jlalmes/trpc-openapi/tree/master). By providing some extra meta-data to your procedures, you can generate an OpenAPI compliant REST API from your tRPC router. +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. -### It's just HTTP Requests +### Ini Hanya Permintaan HTTP -tRPC communicates over HTTP, so it is also possible to call your tRPC procedures using "regular" HTTP requests. However, the syntax can be cumbersome due to the [RPC protocol](https://trpc.io/docs/v10/rpc) that tRPC uses. If you're curious, you can check what tRPC requests and responses look like in your browser's network tab, but we suggest doing this only as an educational exercise and sticking to one of the solutions outlined above. +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. -## Comparison to a Next.js API endpoint +## Perbandingan dengan Endpoint API Next.js -Let's compare a Next.js API endpoint to a tRPC procedure. Let's say we want to fetch a user object from our database and return it to the frontend. We could write a Next.js API endpoint like this: +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"; @@ -227,7 +229,7 @@ const userByIdHandler = async (req: NextApiRequest, res: NextApiResponse) => { const { id } = req.query; if (!id || typeof id !== "string") { - return res.status(400).json({ error: "Invalid id" }); + return res.status(400).json({ error: "ID tidak valid" }); } const examples = await prisma.example.findFirst({ @@ -259,21 +261,21 @@ const UserPage = () => { }; ``` -Compare this to the tRPC example above and you can see some of the advantages of tRPC: +Bandingkan dengan contoh tRPC di atas, Anda dapat melihat beberapa keunggulan tRPC: -- Instead of specifying a url for each route, which can become annoying to debug if you move something, your entire router is an object with autocomplete. -- You don’t need to validate which HTTP method was used. -- You don’t need to validate that the request query or body contains the correct data in the procedure, because Zod takes care of this. -- Instead of creating a response, you can throw errors and return a value or object as you would in any other TypeScript function. -- Calling the procedure on the frontend provides autocompletion and type safety. +- 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. -## Useful snippets +## Potongan Kode Berguna -Here are some snippets that might come in handy. +Berikut beberapa potongan kode yang mungkin berguna. -### Enabling CORS +### Mengaktifkan CORS -If you need to consume your API from a different domain, for example in a monorepo that includes a React Native app, you might need to enable 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"; @@ -283,10 +285,10 @@ import { createTRPCContext } from "~/server/api/trpc"; import cors from "nextjs-cors"; const handler = async (req: NextApiRequest, res: NextApiResponse) => { - // Enable cors + // Aktifkan CORS await cors(req, res); - // Create and call the tRPC handler + // Buat dan panggil handler tRPC return createNextApiHandler({ router: appRouter, createContext: createTRPCContext, @@ -296,9 +298,9 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => { export default handler; ``` -### Optimistic updates +### Pembaruan Optimis -Optimistic updates are when we update the UI before the API call has finished. This gives the user a better experience because they don't have to wait for the API call to finish before the UI reflects the result of their action. However, apps that value data correctness highly should avoid optimistic updates as they are not a "true" representation of backend state. You can read more on the [React Query docs](https://tanstack.com/query/v4/docs/guides/optimistic-updates). +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 = () => { @@ -307,33 +309,35 @@ const MyComponent = () => { const utils = api.useContext(); const postCreate = api.post.create.useMutation({ async onMutate(newPost) { - // Cancel outgoing fetches (so they don't overwrite our optimistic update) + // Batalkan fetch yang sedang berlangsung (sehingga mereka + + tidak mengganti pembaruan optimis kita) await utils.post.list.cancel(); - // Get the data from the queryCache + // Dapatkan data dari queryCache const prevData = utils.post.list.getData(); - // Optimistically update the data with our new post + // Perbarui data secara optimis dengan pos baru kita utils.post.list.setData(undefined, (old) => [...old, newPost]); - // Return the previous data so we can revert if something goes wrong + // Kembalikan data sebelumnya sehingga kita dapat mengembalikannya jika terjadi masalah return { prevData }; }, onError(err, newPost, ctx) { - // If the mutation fails, use the context-value from onMutate + // Jika mutasi gagal, gunakan nilai konteks dari onMutate utils.post.list.setData(undefined, ctx.prevData); }, onSettled() { - // Sync with server once mutation has settled + // Sinkronkan dengan server setelah mutasi selesai utils.post.list.invalidate(); }, }); }; ``` -### Sample Integration Test +### Contoh Pengujian Integrasi -Here is a sample integration test that uses [Vitest](https://vitest.dev) to check that your tRPC router is working as expected, the input parser infers the correct type, and that the returned data matches the expected output. +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"; @@ -342,25 +346,25 @@ import { expect, test } from "vitest"; import { appRouter, type AppRouter } from "~/server/api/root"; import { createInnerTRPCContext } from "~/server/api/trpc"; -test("example router", async () => { +test("contoh router", async () => { const ctx = await createInnerTRPCContext({ session: null }); const caller = appRouter.createCaller(ctx); - type Input = inferProcedureInput; + type Input = inferProcedureInput; const input: Input = { - text: "test", + teks: "tes", }; - const example = await caller.example.hello(input); + const contoh = await caller.contoh.halo(input); - expect(example).toMatchObject({ greeting: "Hello test" }); + expect(contoh).toMatchObject({ sapaan: "Halo tes" }); }); ``` -If your procedure is protected, you can pass in a mocked `session` object when you create the context: +Jika prosedur Anda dilindungi, Anda dapat melewatkan objek `session` yang dimock saat Anda membuat konteks: ```ts -test("protected example router", async () => { +test("contoh router yang dilindungi", async () => { const ctx = await createInnerTRPCContext({ session: { user: { id: "123", name: "John Doe" }, @@ -373,10 +377,10 @@ test("protected example router", async () => { }); ``` -## Useful Resources +## Sumber Daya Berguna -| Resource | Link | -| ---------------------- | ------------------------------------------------------- | -| tRPC Docs | https://www.trpc.io | -| Bunch of tRPC Examples | https://github.com/trpc/trpc/tree/next/examples | -| React Query Docs | https://tanstack.com/query/v4/docs/adapters/react-query | +| 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 index 833fd5b2bc..f7742ee91a 100644 --- a/www/src/pages/id/usage/typescript.md +++ b/www/src/pages/id/usage/typescript.md @@ -1,14 +1,14 @@ --- title: TypeScript -description: Usage of TypeScript +description: Penggunaan TypeScript layout: ../../../layouts/docs.astro -lang: en +lang: id ---

- Build safety nets, not guard rails + Bangun jaringan keamanan, bukan pagar pelindung

@@ -18,7 +18,7 @@ lang: en src="/images/theo_300x300.webp" />
-Whether you're a new or seasoned developer, we think that TypeScript is a must have. It can look intimidating at first, but much like a lot of tools, is something that many never look back from after starting to use it. +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. -It provides live feedback as you write your code by defining expected data types, and either provides helpful autocomplete in your code editor, or yells at you with red squiggly lines if you're trying to access a property that doesn't exist or trying to pass a value of the wrong type, which you would otherwise have to debug further down the line. +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. -It is, perhaps, the tool that provides the most productivity to developers; providing documentation of the code you're writing or consuming directly in your editor, and having instant feedback as you inevitably make mistakes is absolutely priceless. +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. -## Type Inference +## Inferensi Tipe -While many new TypeScript developers are concerned with _writing_ TypeScript, many of its benefits don't actually require you to change your code at all, in particular inference. Inference means that if something is typed, that type will follow it throughout the flow of the application without having to be re-declared in other places. This means that for example once you have defined the types of the arguments that a function takes, the remainder of the function will usually be typesafe without requiring any further TypeScript-specific code. Library developers put a ton of work into maintaining the types for their libraries, which means that we as application developers can benefit from both the inference and the built-in documentation in your code editor that these types provide. +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.
- +
-Check out Theo's video on how [you might be using TypeScript wrong](https://www.youtube.com/watch?v=RmGHnYUqQ4k). +Lihat video Theo tentang [Anda mungkin salah menggunakan TypeScript](https://www.youtube.com/watch?v=RmGHnYUqQ4k). -## Powerful uses of type inference +## Penggunaan Kuat dari Inferensi Tipe ### Zod -[Zod](https://github.com/colinhacks/zod) is a schema validation library that is built on top of TypeScript. Write a schema that represents a single source of truth for your data, and Zod will ensure that your data is valid throughout your application, even across network boundaries and external APIs. +[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/) gives you declarative, always-up-to-date auto-managed queries and mutations that directly improve both your developer and user experiences. +[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. -## Useful Resources +## Sumber Daya Berguna -| Resource | Link | -| --------------------------------------------------------- | ----------------------------------------------------------------- | -| TypeScript Handbook | https://www.typescriptlang.org/docs/handbook/ | -| Beginners TypeScript Tutorial | https://github.com/total-typescript/beginners-typescript-tutorial | -| Type Challenges | https://github.com/type-challenges/type-challenges | -| Rodney Mullen of TypeScript (Matt Pocock) Youtube Channel | https://www.youtube.com/c/MattPocockUk/videos | +| Sumber Daya | Tautan | +| -------------------------------------- | ------------------------------------------------------------------- | +| Panduan TypeScript | | +| Tutorial TypeScript untuk Pemula | | +| Tantangan Tipe | | +| Saluran Youtube "Rodney Mullen" (Matt Pocock) tentang TypeScript | | From adc3540f6bb8b31801f0cdc53805e5a69429c69e Mon Sep 17 00:00:00 2001 From: Imamuzzaki Abu Salam Date: Mon, 30 Oct 2023 09:44:21 +0700 Subject: [PATCH 12/13] fix(i18n): Update sidebar entry for "Usage" in Indonesian language --- www/src/pages/id/usage/index.astro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/src/pages/id/usage/index.astro b/www/src/pages/id/usage/index.astro index d984789d84..37df55c5a7 100644 --- a/www/src/pages/id/usage/index.astro +++ b/www/src/pages/id/usage/index.astro @@ -12,7 +12,7 @@ const frontmatter: Frontmatter = { }; const lang = getLanguageFromURL(Astro.url.pathname); -const sidebarEntries = SIDEBAR[lang]["Pemakaian"]!; +const sidebarEntries = SIDEBAR[lang]["Usage"]!; const files = await Astro.glob("./*.{md,mdx,astro}"); --- From 25bbe0822809b8466439ce3a66724c062699ec6b Mon Sep 17 00:00:00 2001 From: Imamuzzaki Abu Salam Date: Mon, 30 Oct 2023 09:53:43 +0700 Subject: [PATCH 13/13] style: run prettier --- www/src/pages/id/deployment/docker.md | 20 ++++++++++---------- www/src/pages/id/usage/index.astro | 3 ++- www/src/pages/id/usage/next-js.md | 16 ++++++++-------- www/src/pages/id/usage/prisma.md | 14 +++++++------- www/src/pages/id/usage/tailwind.md | 18 +++++++++--------- www/src/pages/id/usage/trpc.md | 8 ++++---- www/src/pages/id/usage/typescript.md | 10 +++++----- 7 files changed, 45 insertions(+), 44 deletions(-) diff --git a/www/src/pages/id/deployment/docker.md b/www/src/pages/id/deployment/docker.md index f2a20ae7a9..332ddffc34 100644 --- a/www/src/pages/id/deployment/docker.md +++ b/www/src/pages/id/deployment/docker.md @@ -204,13 +204,13 @@ Buka "Variables" dan sertakan `DATABASE_URL` Anda. Kemudian buka "Settings" dan ## 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 | | +| 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/usage/index.astro b/www/src/pages/id/usage/index.astro index 37df55c5a7..8260ab7530 100644 --- a/www/src/pages/id/usage/index.astro +++ b/www/src/pages/id/usage/index.astro @@ -8,7 +8,8 @@ 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.", + description: + "Pelajari bagaimana cara memakai berbagai teknologi dari Stack T3.", }; const lang = getLanguageFromURL(Astro.url.pathname); diff --git a/www/src/pages/id/usage/next-js.md b/www/src/pages/id/usage/next-js.md index c32fba417c..64a19fca44 100644 --- a/www/src/pages/id/usage/next-js.md +++ b/www/src/pages/id/usage/next-js.md @@ -27,11 +27,11 @@ Jika Anda perlu menggunakan fitur ini, periksa tautan-tautan berikut: [Advanced ## 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 | | +| 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 index 61f989c689..a565d62394 100644 --- a/www/src/pages/id/usage/prisma.md +++ b/www/src/pages/id/usage/prisma.md @@ -69,10 +69,10 @@ Kemudian, cukup jalankan `pnpm db-seed` (atau `npm`/`yarn`) untuk menyemai basis ## Sumber Daya Berguna -| Sumber Daya | Tautan | -| ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | -| Dokumentasi Prisma | | -| GitHub Prisma | | -| Prisma Migrate Playground | | -| Adapter Prisma NextAuth.JS | | -| Panduan Koneksi Planetscale | | +| 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 index 29e1bfd6c9..3a5dd099f6 100644 --- a/www/src/pages/id/usage/tailwind.md +++ b/www/src/pages/id/usage/tailwind.md @@ -85,12 +85,12 @@ Menggunakan kelas secara kondisional dengan menggunakan operator ternary bisa me ## Sumber Daya Berguna -| Sumber Daya | Tautan | -| ---------------------------- | ------------------------------------------------------------------ | -| Dokumentasi Tailwind | | -| Daftar Cepat Tailwind | | -| awesome-tailwindcss | | -| Komunitas Tailwind | | -| Server Discord Tailwind | | -| Kanal Youtube TailwindLabs | | -| Tailwind Playground | | +| 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 index efb9659adb..c5a1f09b3c 100644 --- a/www/src/pages/id/usage/trpc.md +++ b/www/src/pages/id/usage/trpc.md @@ -379,8 +379,8 @@ test("contoh router yang dilindungi", async () => { ## Sumber Daya Berguna -| Sumber Daya | Tautan | -| ------------------- | ------------------------------------------------------- | -| Dokumentasi tRPC | | -| Banyak Contoh tRPC | | +| 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 index f7742ee91a..6e82eacaab 100644 --- a/www/src/pages/id/usage/typescript.md +++ b/www/src/pages/id/usage/typescript.md @@ -59,9 +59,9 @@ Lihat video Theo tentang [Anda mungkin salah menggunakan TypeScript](https://www ## Sumber Daya Berguna -| Sumber Daya | Tautan | -| -------------------------------------- | ------------------------------------------------------------------- | -| Panduan TypeScript | | -| Tutorial TypeScript untuk Pemula | | -| Tantangan Tipe | | +| Sumber Daya | Tautan | +| ---------------------------------------------------------------- | ------------------------------------------------------------------- | +| Panduan TypeScript | | +| Tutorial TypeScript untuk Pemula | | +| Tantangan Tipe | | | Saluran Youtube "Rodney Mullen" (Matt Pocock) tentang TypeScript | |