diff --git a/www/src/config.ts b/www/src/config.ts index f003da3d89..8d917dc8d8 100644 --- a/www/src/config.ts +++ b/www/src/config.ts @@ -37,6 +37,7 @@ export const KNOWN_LANGUAGES = { no: "Norsk", pl: "Polski", "zh-hans": "简体中文", + tr: "Türkçe", } as const; export type KnownLanguageCode = keyof typeof KNOWN_LANGUAGES; @@ -366,6 +367,35 @@ export const SIDEBAR: Sidebar = { { text: "Docker", link: "zh-hans/deployment/docker" }, ], }, + tr: { + "Create T3 App": [ + { text: "Giriş", link: "tr/introduction" }, + { text: "Neden CT3A?", link: "tr/why" }, + { text: "Kurulum", link: "tr/installation" }, + { text: "Klasör Yapısı", link: "tr/folder-structure" }, + { text: "S. S. S.", link: "tr/faq" }, + { text: "T3 Koleksiyonu", link: "tr/t3-collection" }, + { text: "Diğer Öneriler", link: "tr/other-recs" }, + ], + Usage: [ + { text: "İlk Adımlar", link: "tr/usage/first-steps" }, + { text: "Next.js", link: "tr/usage/next-js" }, + { text: "TypeScript", link: "tr/usage/typescript" }, + { text: "tRPC", link: "tr/usage/trpc" }, + { text: "Prisma", link: "tr/usage/prisma" }, + { text: "NextAuth.js", link: "tr/usage/next-auth" }, + { + text: "Ortam Değişkenleri", + link: "tr/usage/env-variables", + }, + { text: "Tailwind CSS", link: "tr/usage/tailwind" }, + ], + Deployment: [ + { text: "Vercel", link: "tr/deployment/vercel" }, + { text: "Netlify", link: "tr/deployment/netlify" }, + { text: "Docker", link: "tr/deployment/docker" }, + ], + }, }; export const SIDEBAR_HEADER_MAP: Record< @@ -423,4 +453,9 @@ export const SIDEBAR_HEADER_MAP: Record< Usage: "用法", Deployment: "部署", }, + tr: { + "Create T3 App": "Create T3 App", + Usage: "Kullanım", + Deployment: "Dağıtım", + }, }; diff --git a/www/src/pages/tr/deployment/docker.md b/www/src/pages/tr/deployment/docker.md new file mode 100644 index 0000000000..672668001f --- /dev/null +++ b/www/src/pages/tr/deployment/docker.md @@ -0,0 +1,214 @@ +--- +title: Docker +description: Docker ile Dağıtım +layout: ../../../layouts/docs.astro +lang: en +--- + +Bu stack'i konteynerize ederek Docker ile tek konteyner olarak veya docker-compose kullanarak bir konteyner grubunun parçası olarak dağıtımını yapabilirsiniz. Bu dokümantasyona göre oluşturulmuş örnek projeye bakabilirsiniz: [`ajcwebdev/ct3a-docker`](https://github.com/ajcwebdev/ct3a-docker) + +## Docker Proje Konfigürasyonu + +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 Konfigürasyonu + +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. dockerignore dosyasını oluşturun + +
+ + 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.16 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.16 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.16 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/tr/deployment/index.astro b/www/src/pages/tr/deployment/index.astro new file mode 100644 index 0000000000..4b6761d9cc --- /dev/null +++ b/www/src/pages/tr/deployment/index.astro @@ -0,0 +1,24 @@ +--- +import Layout from "../../../layouts/docs.astro"; +import IndexPage from "../../../components/docs/indexPage.astro"; +import { Frontmatter, SIDEBAR } from "../../../config"; +import { getLanguageFromURL } from "../../../languages"; + +const frontmatter: Frontmatter = { + title: "Dağıtım", + layout: "docs", + description: "T3 projeni nasıl üretime dağıtacağını öğren.", +}; + +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/tr/deployment/netlify.md b/www/src/pages/tr/deployment/netlify.md new file mode 100644 index 0000000000..dc6f3896dd --- /dev/null +++ b/www/src/pages/tr/deployment/netlify.md @@ -0,0 +1,86 @@ +--- +title: Netlify +description: Netlify ile Dağıtım +layout: ../../../layouts/docs.astro +lang: en +--- + +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). + +> _NOTE: 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/tr/deployment/vercel.md b/www/src/pages/tr/deployment/vercel.md new file mode 100644 index 0000000000..936010ffec --- /dev/null +++ b/www/src/pages/tr/deployment/vercel.md @@ -0,0 +1,63 @@ +--- +title: Vercel +description: Vercel ile Dağıtım +layout: ../../../layouts/docs.astro +lang: tr +--- + +Projenizi [Vercel](https://vercel.com/?utm_source=t3-oss&utm_campaign=oss) ile dağıtmanızı öneriyoruz. Next.js uygulamalarını dağıtmayı çok kolaylaştırıyor. + +## Proje Konfigürasyonu + +Vercel, build komutunu konfigüre etmek ve dizini otomatik olarak yayınlamaya eğilimlidir. Bunun yanı sıra, bir [`vercel.json`](https://vercel.com/docs/project-configuration) dosyası oluşturarak diğer konfigürasyonlarla birlikte bu bilgileri de tanımlayabilirsiniz. **Bu, çoğu proje için gerekli değildir.** + +```json +{ + "buildCommand": "npm run build", + "outputDirectory": "dist", + "devCommand": "npm run dev", + "installCommand": "npm install" +} +``` + +## Vercel Kontrol Panelini Kullanmak + +1. Kodunuzu GitHub projenize ekledikten sonra [Vercel](https://vercel.com/?utm_source=t3-oss&utm_campaign=oss)'e GitHub hesabınız ile kayıt olun ve **Add New Project** butonuna tıklayın. + +![New project on Vercel](/images/vercel-new-project.webp) + +2. GitHub projeniz ile bağlantıyı kurun. + +![Import repository](/images/vercel-import-project.webp) + +3. Ortam değişkenlerinizi ekleyin. + +![Add environment variables](/images/vercel-env-vars.webp) + +4. **Deploy** tuşuna basın. Artık ne zaman yeni bir değişiklik yapsanız, Vercel otomatik olarak projenizi tekrar dağıtacak! + +## Vercel CLI Kullanımı + +Komut isteminden dağıtım yapmak için öncelikle [Vercel CLI'ını yüklemelisiniz](https://vercel.com/docs/cli#installing-vercel-cli). + +```bash +npm i -g vercel +``` + +Projenizin dağıtımını yapmak için [`vercel`](https://vercel.com/docs/cli/deploying-from-cli) komutunu kullanın. + +```bash +vercel +``` + +Veritabanı bağlantı dizgisi gibi ortam değişkenleri için `--env DATABASE_URL=VERITABANI_STRING` seçeneğini dahil edebilirsiniz. Dağıtım sorularını atlayıp hepsine varsayılan cevabı vermek istiyorsanız `--yes` seçeneğini kullanın. + +```bash +vercel --env DATABASE_URL=VERITABANI_STRING --yes +``` + +İlk dağıtımdan sonra bu komut, önizleme branch'ine dağıtım yapacak. Gelecekteki dağıtımlarda değişiklikleri doğrudan canlı siteye uygulamak için `--prod` seçeneğini eklemeniz gerekir. + +```bash +vercel --prod +``` diff --git a/www/src/pages/tr/faq.md b/www/src/pages/tr/faq.md new file mode 100644 index 0000000000..81ff7cfae2 --- /dev/null +++ b/www/src/pages/tr/faq.md @@ -0,0 +1,61 @@ +--- +title: S. S. S. +description: Create T3 App hakkında sıkça sorulan sorular +layout: ../../layouts/docs.astro +lang: tr +--- + +İşte `create-t3-app` hakkında sıkça sorulan sorular. + +## Sonrasında ne var? Bununla nasıl uygulama geliştirebilirim? + +Bu projeyi olabildiğince basit tutmaya çalışıyoruz, bizim oluşturduğumuz şablon ile başlayabilirsiniz ve daha sonra gerektiğinde istediğiniz eklentiyi ekleyebilirsiniz. + +Eğer bu projede kullanılan farklı teknolojilerden haberdar değilseniz, lütfen teknolojinin kendi dokümantasyonuna bakınız. Eğer hala emin olamadıysanız, lütfen [Discord](https://t3.gg/discord) sunucumuza katılıp yardım isteyin. + +- [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) + +## Şu anda nereden öğrenebilirim? + +Aşağıda listelenen kaynaklar T3 Stack'ini öğrenmek için en iyi kaynaklar olmasına karşın, topluluk (ve [Theo](https://youtu.be/rzwaaWH0ksk?t=1436)) stack ile bir yerden başlayıp geliştirme yaparken öğrenmenizi öneriyor. + +`create-t3-app` kullanmayı düşünüyorsanız, muhtemelen daha önce stack'in bazı parçalarını kullanmışsınızdır. Öyleyse neden bodoslama dalıp bir şeyler geliştirirken diğer kısımları öğrenmiyorsunuz? + +Tabii ki bu yöntem herkes için uygun değil. Önerimizi denediğinizi düşünüyor fakat hala öğrenmek için kaynak arıyorsanız, veya öneriyi kendi başınıza deneyecek kadar kendinizden emin değilseniz, veya belki stack size çok fazla gelmişse, o zaman aşağıdaki harika `create-t3-app` derslere göz atabilirsiniz: + +### Yazılar + +- [Build a full stack app with create-t3-app](https://www.nexxel.dev/blog/ct3a-guestbook) +- [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) + +### Videolar + +- [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) + +## Neden projede `.js` dosyaları var? + +[T3-Aksiyomu #3](/en/introduction#typesafety-isnt-optional) göz önünde bulundurularak, type-güvenliğini birinci sınıf vatandaş olarak kabul ediyoruz. Maalesef, tüm framework'ler ve eklentiler TypeScript'i desteklemiyor. Bu yüzden, bazı konfigürasyon dosyaları `.js` uzantılı olmalı. + +Bu dosyaların bir nedenden dolayı JavaScript olduğunu vurgulamaya çalışıyoruz ve kullanıldığı kütüphane tarafından desteklenen dosya türünü (`cjs` veya `mjs`) açıkça belirterek bunu gerçekleştiriyoruz. Ayrıca, bu projedeki tüm `js` dosyalarına hala en üstteki `@ts-check` ile type kontrolü yapılmaktadır. + +## Uygulamama i18n eklemekte zorlanıyorum. Kullanabileceğim bir referans var mı? + +`create-t3-app` içerisinde i18n bulundurmamaya karar verdik çünkü çok tartışılan bir konu ve birden fazla uygulanma yolu var. + +Fakat, eğer eklemekte zorlanıyorsanız ve bir referans projesi görmek istiyorsanız [next-18next](https://github.com/i18next/next-i18next) kullanarak nasıl T3 Uygulamanıza i18n ekleyebileceğinizi gösteren bir [referans projemiz](https://github.com/juliusmarminge/t3-i18n) var. + +## Neden Next.js 13 ile gelen `/app` yerine `/pages` kullanıyoruz? + +[T3-Aksiyomu #2](/en/introduction#bleed-responsibly) göz önünde bulundurularak, son teknoloji şeyleri seviyoruz fakat istikrarlığa da önem veriyoruz, router'ınızın tamamını portlamak çok mu zor, [muhtemelen son teknoloji için iyi bir yer değil](https://youtu.be/mnwUbtieOuI?t=1662). `/app` ne kadar [geleceğe göz kırpsa da](https://youtu.be/rnsC-12PVlM?t=818), gerçek hayat için hazır değil. API daha hala betada ve büyük değişikliklerin gelmesi bekleniyor. + +`/app` için desteklenen, planlanan ve üzerinde çalışılan tüm özelliklerin listesini görmek isterseniz [beta Next.js dokümantasyonunu](https://beta.nextjs.org/docs/app-directory-roadmap#supported-and-planned-features) ziyaret edebilirsiniz. diff --git a/www/src/pages/tr/folder-structure.mdx b/www/src/pages/tr/folder-structure.mdx new file mode 100644 index 0000000000..8cf97f937f --- /dev/null +++ b/www/src/pages/tr/folder-structure.mdx @@ -0,0 +1,233 @@ +--- +title: Folder Structure +description: Folder structure of a newly scaffolded T3 App +layout: ../../layouts/docs.astro +lang: en +--- + +import Form from "../../components/docs/folderStructureForm.astro"; +import Diagram from "../../components/docs/folderStructureDiagram.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. The `examples.ts` file contains an example of a route that uses the [Next.js API route](https://nextjs.org/docs/api-routes/introduction) feature along with Prisma. The `restricted.ts` file contains an example of a route that uses the [Next.js API route](https://nextjs.org/docs/api-routes/introduction) feature and is protected by [NextAuth.js](https://next-auth.js.org/). + +
+
+ +#### `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/common` + +The `common` folder contains commonly re-used server-side code. + +
+
+ +#### `src/server/common/get-server-auth-session.ts` + +The `get-server-auth-session.ts` file is used to get the NextAuth.js session on the server-side. See [NextAuth.js usage](usage/next-auth#usage-with-trpc) for more information. + +
+
+ +#### `src/server/db/client.ts` + +The `client.ts` file is used to instantiate the Prisma client at global scope. See [Prisma usage](usage/prisma#prisma-client) for more information. + +
+
+ +### `src/server/trpc` + +The `trpc` folder contains the tRPC server-side code. + +
+
+ +#### `src/server/trpc/context.ts` + +The `context.ts` file is used to create the context used in tRPC requests. See [tRPC usage](usage/trpc#-servertrpccontextts) for more information. + +
+
+ +#### `src/server/trpc/trpc.ts` + +The `trpc.ts` file is used to export procedure helpers. See [tRPC usage](usage/trpc#-servertrpctrpcts) for more information. + +
+
+ +### `src/server/trpc/router` + +The `router` folder contains the tRPC routers. + +
+
+ +#### `src/server/trpc/router/_app.ts` + +The `_app.ts` file is used to merge tRPC routers and export them as a single router, as well as the type definitions. See [tRPC usage](usage/trpc#-servertrpcrouterts) for more information. + +
+
+ +#### `src/server/trpc/router/auth.ts` + +The `auth.ts` file is an example tRPC router utilizing the `protectedProcedure` helper to demonstrate how to protect a tRPC route with NextAuth.js. + +
+
+ +#### `src/server/trpc/router/example.ts` + +The `example.ts` file is an example tRPC router utilizing the `publicProcedure` helper to demonstrate how to create a public tRPC route. + +
+
+ +### `src/styles` + +The `styles` folder contains the global styles of the application. + +
+
+ +### `src/types` + +The `types` folder is used to store reused types or type declarations. + +
+
+ +#### `src/types/next-auth.d.ts` + +The `next-auth.d.ts` file is used to extend the NextAuth.js default session type to include the user ID. See [NextAuth.js usage](usage/next-auth#inclusion-of-userid-on-the-session) for more information. + +
+
+ +### `src/utils` + +The `utils` folder is used to store commonly re-used utility functions. + +
+
+ +#### `src/utils/trpc.ts` + +The `trpc.ts` file is the front-end entrypoint to tRPC. See [tRPC usage](usage/trpc#-utilstrpcts) 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.json` + +The `.eslintrc.json` 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.cjs` + +The `prettier.config.cjs` 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. + +
diff --git a/www/src/pages/tr/installation.md b/www/src/pages/tr/installation.md new file mode 100644 index 0000000000..386201aa78 --- /dev/null +++ b/www/src/pages/tr/installation.md @@ -0,0 +1,61 @@ +--- +title: Kurulum +description: Create T3 App için kurulum talimatları +layout: ../../layouts/docs.astro +lang: tr +--- + +`create-t3-app` kullanarak bir uygulama oluşturmak için aşağıdaki üç komuttan birini çalıştırın ve daha sonra karşınıza çıkan soruları yanıtlayın: + +### npm + +```bash +npm create t3-app@latest +``` + +### yarn + +```bash +yarn create t3-app +``` + +### pnpm + +```bash +pnpm create t3-app@latest +``` + +Uygulamanız oluşturulduktan sonra, yeni uygulamanıza başlamak için [ilk adımlar](/tr/usage/first-steps) sayfasını inceleyin. + +## Gelişmiş kullanım + +| Seçenek | Açıklama | +| ----------------- | ------------------------------------------------------------------------ | +| `[dir]` | Proje adını içeren bir klasör argümanı ekleyin | +| `--noGit` | Uygulamanız için yeni bir git projesi oluşturmamasını özellikle belirtin | +| `-y`, `--default` | Soruları atlayarak yeni projenizi varsayılan ayarlarla oluşturun | +| `--noInstall` | Gerekli kütüphaneleri yüklemeyerek projeyi oluşturun | + +## Deneysel kullanım + +CI için, herhangi bir soru cevaplamak zorunda kalmayadan uygulama oluşturabileceğiniz deneysel seçeneklerimiz var. Eğer bu kullanım size uyuyorsa, bu seçenekleri kullanabilirsiniz. Lütfen bu seçeneklerin deneysel olduğunu ve ileride semver versiyonlamayı takip etmeyerek değişebileceğini aklınızda bulundurun. + +| Seçenek | Açıklama | +| ------------ | ------------------------------- | +| `--CI` | CI modunda olduğunuzu belirtin | +| `--trpc` | Projeye tRPC dahil edin | +| `--prisma` | Projeye Prisma dahil edin | +| `--nextAuth` | Projeye NextAuth.js dahil edin | +| `--tailwind` | Projeye Tailwind CSS dahil edin | + +**Not: Eğer `CI` seçeneğini koymazsanız geri kalan tüm seçenekler geçersiz sayılır.** + +İstemediğiniz eklentileri özellikle belirtmek zorunda değilsiniz. Fakat, belirtmek isterseniz, `false` argümanını kullanabilirsiniz, örneğin `--nextAuth false`. + +### Örnek + +Aşağıdaki komut, tRPC ve Tailwind CSS kullanarak bir T3 Uygulaması oluşturur. + +```bash +pnpm dlx create-t3-app@latest --CI --trpc --tailwind +``` diff --git a/www/src/pages/tr/introduction.md b/www/src/pages/tr/introduction.md new file mode 100644 index 0000000000..7b1980a682 --- /dev/null +++ b/www/src/pages/tr/introduction.md @@ -0,0 +1,42 @@ +--- +title: Giriş +description: T3 Stack'ine Giriş +layout: ../../layouts/docs.astro +lang: tr +--- + +
+ +
+ +## T3 Stack + +_"T3 Stack"_, [Theo](https://twitter.com/t3dotgg) tarafından geliştirilen; kolaylık, modülerlik ve full-stack type-güvenliğine odaklanan bir web geliştirme stack'idir. + +İçinde hemen hemen her zaman [**Next.js**](https://nextjs.org/) ve [**TypeScript**](https://typescriptlang.org/) temelini barındırır. Eğer backend benzeri işler de yapıyorsanız [**tRPC**](https://trpc.io/), [**Prisma**](https://prisma.io/) ve [**NextAuth.js**](https://next-auth.js.org/) projenize güzel eklentiler olabilir. + +Fark ettiğiniz üzere çok… fazla kütüphane/eklenti var. Bu şekilde tasarlandı. Bu parçaları istediğiniz gibi çıkarıp ekleyin. Stack, özünde modüler :) + +## Peki... create-t3-app nedir? Bir şablon mu? + +Gibi diyebiliriz? `create-t3-app`, T3 Stack geliştiricileri tarafından oluşturulan bir CLI'dır ve modüler bir T3 Stack projesinin kurulumunu hızlandırır. Bu, tüm eklentilerin isteğe bağlı olduğu ve "şablon"un ihtiyaçlarınıza göre oluşturulduğu anlamına gelir. + +Sayısız proje ve bu teknoloji üzerinde yıllar boyunca uğraştıktan sonra birçok fikrimiz ve öngörülerimiz var. Onları bu CLI'a uygulayabilmek için elimizden gelenin en iyisini yaptık. + +Bu, her şey dahil bir şablon **DEĞİLDİR**. Sizden **KENDİ** projenizdeki bir sorunu çözmeniz için kendi kütüphanelerinizi kullanmanız **beklenir**. State yönetimi veya dağıtım gibi özel problemlerin çözümlerini tek tek yazmak istemediğimiz gibi [birkaç önerimizi de buradan bulabilirsiniz](/tr/other-recs). + +## T3 Aksiyomları + +Açık sözlü olacağız - bu _dogma bir proje_. Geliştiricilik üzerinde birkaç temel inanç paylaşıyoruz ve bunları kararlarımızın temeli olarak kabul ediyoruz. + +### Problem Çözmek + +"hepsini eklemek" gibi bir hataya düşmek oldukça kolay - sizden özellikle bunu yapmanızı istemiyoruz. `create-t3-app` içine eklenen her şey, içinde bulunan temel teknolojilerde var olan bir belirli sorunu çözmelidir. Bu, (`zustand`, `redux` ) gibi state kütüphanelerini buraya eklemeyeceğimiz anlamına gelir, ancak NextAuth.js gibi şeyleri ekleyecek ve Prisma ve tRPC'yi sizin için entegre edeceğiz. + +### Yeni Teknolojileri Sorumlu Kullanmak + +En yeni teknolojilere bayılıyoruz. Yeni teknolojilerdeki hız miktarı ve dürüst olmak gerekirse, eğlence, çok güzel. Yeni teknolojileri sorumlu kullanmanın önemli olduğunu düşündüğümüz için riskli yeni teknolojileri az riskli yerlerde kullanıyoruz. Bu, yeni ve riskli bir veritabanı teknolojisine (SQL iyidir!) yanaşmayacağımız ⛔️ anlamına gelir. Ancak bırakmanın kolay ve önemsiz olduğu tRPC'ye mutlu bir şekilde ✅ yanaşırız. + +### Zorunlu Type-güvenliği + +`create-t3-app`'in asıl amacı en hızlı şekilde yeni full-stack ve **type-güvenli** bir web uygulaması oluşturmak. Verimliliğimizi artırdığı için ve daha az hatalı kodu kullanıcıya sunmayı sağladığı için type-güvenliğini ciddiye alıyoruz. `create-t3-app`'in type-güvenli doğasıyla çelişen herhangi bir karar, farklı bir projede işi olan bir karardır. diff --git a/www/src/pages/tr/other-recs.md b/www/src/pages/tr/other-recs.md new file mode 100644 index 0000000000..0ffbdce306 --- /dev/null +++ b/www/src/pages/tr/other-recs.md @@ -0,0 +1,161 @@ +--- +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) + +### 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. + +- [Umami Homepage](https://umami.is/) +- [Umami GitHub](https://github.com/umami-software/umami) + +## 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/tr/t3-collection.md b/www/src/pages/tr/t3-collection.md new file mode 100644 index 0000000000..21378df885 --- /dev/null +++ b/www/src/pages/tr/t3-collection.md @@ -0,0 +1,42 @@ +--- +title: T3 Collection +description: Cool open source projects and companies using the T3 stack +layout: ../../layouts/docs.astro +lang: en +--- + +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 + +| Description | Repo | Link | +| ----------------------------------------------------------------- | --------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | +| Create T3 Turbo - T3 Stack using Turborepo | [create-t3-turbo](https://github.com/t3-oss/create-t3-turbo) | [create-t3-turbo.vercel.app](https://create-t3-turbo.vercel.app/) | +| Zapdos - a QnA app for streamers | [pingdotgg/zapdos](https://github.com/pingdotgg/zapdos) | [ask.ping.gg](https://ask.ping.gg) | +| Shoutify - Free, open-source, self-hosted social media management | [techsquidtv/shoutify](https://github.com/TechSquidTV/Shoutify) | [shoutify.app](https://github.com/TechSquidTV/Shoutify) (coming soon) | +| Me3 - Describe yourself in 3 things and share with your friends. | [hnqg/me3](https://github.com/hnqg/me3) | [me3.hnqg.io](https://me3.hnqg.io) | +| Josh's personal site | [joshhyde9/portfolio](https://github.com/JoshHyde9/portfolio) | [joshhyde.me](https://joshhyde.me) | +| Cal.com - Scheduling infrastructure for absolutely everyone. | [calcom/cal.com](https://github.com/calcom/cal.com) | [cal.com](https://cal.com) | +| My FAQ Page - An FAQ Page generator | [ronanru/myfaq.page](https://github.com/ronanru/myfaq.page) | [MyFAQ.page](https://myfaq.page) | +| Tincy Pics - A tincy wincy image host | [mozzius/tincypics](https://github.com/mozzius/tincypics) | [tincy.pics](https://tincy.pics) | +| Ayanava's Guestbook | [AyanavaKarmakar/Guestbook](https://github.com/AyanavaKarmakar/Guestbook) | [guestbook.ayanavakarmakar.software](https://guestbook.ayanavakarmakar.software/) | +| Slug - URL Shortener | [pheralb/slug](https://github.com/pheralb/slug) | [slug.vercel.app](https://slug.vercel.app) | +| AI TTS Donations - FOSS AI Text To Speech service for Streamers. | [mmattDonk/AI-TTS-Donations](https://github.com/mmattDonk/AI-TTS-Donations) | [staging.solrock.mmattDonk.com](https://staging.solrock.mmattDonk.com) | +| The Doom | [moltivie/slug](https://github.com/Moltivie/the-t3-stack) | [the-t3-stack.vercel.app](https://the-t3-stack.vercel.app) | +| Railtrack | [noahflk/railtrack](https://github.com/noahflk/railtrack) | [railtrack.flk.li](https://railtrack.flk.li) | +| KARA Shop - Ecommerce website | [mehrabmp/kara-shop](https://github.com/mehrabmp/kara-shop) | [karashop.vercel.app](https://karashop.vercel.app/) | +| Tauri T3 App - Tauri App using T3 Stack | [tauri-t3-app](https://github.com/AyanavaKarmakar/tauri-t3-app) | [tauri-t3-app.docs](https://github.com/AyanavaKarmakar/tauri-t3-app#readme) | +| Azon - E-Commerce website | [andrewsolonets/Azon-Shop](https://github.com/andrewsolonets/Azon-Shop) | [azon-shop.vercel.app](https://azon-shop.vercel.app/) | +| Analyzemyrepo.com - Usefull insights for **any** GitHub repo | [CrowdDotDev/analyzemyrepo](https://github.com/CrowdDotDev/analyzemyrepo) | [analyzemyrepo.com](https://analyzemyrepo.com) | + +## 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! + +| Company | Link | +| ------- | ---------------------------------- | +| Ping.gg | [ping.gg](https://ping.gg) | +| Nexiona | [nexiona.com](https://nexiona.com) | +| Layer3 | [layer3.xyz](https://layer3.xyz) | + +_Have a cool project using the T3 stack? Make a [pull request](https://github.com/t3-oss/create-t3-app/tree/next/www/src/pages/en/t3-collection.md) and add it here!_ diff --git a/www/src/pages/tr/usage/env-variables.md b/www/src/pages/tr/usage/env-variables.md new file mode 100644 index 0000000000..07358f4df8 --- /dev/null +++ b/www/src/pages/tr/usage/env-variables.md @@ -0,0 +1,127 @@ +--- +title: Environment Variables +description: Getting started with create-t3-app +layout: ../../../layouts/docs.astro +lang: en +--- + +Create-T3-App uses [Zod](https://github.com/colinhacks/zod) for validating your environment variables at runtime _and_ buildtime by providing some additional files in the `env`-directory: + +📁 src/env + +┣ 📄 client.mjs + +┣ 📄 schema.mjs + +┣ 📄 server.mjs + +The content of these files may seem scary at first glance, but don't worry, it's not as complicated as it looks. Let's take a look at them one by one, and walk through the process of adding additional environment variables. + +_TLDR; If you want to add a new environment variable, you must add it to both your `.env` as well as define the validator in `env/schema.mjs`._ + +## schema.mjs + +This is the file you will actually touch. It contains two schemas, one for server-side environment variables and one for client-side as well as a `clientEnv` object. + +```ts:env/schema.mjs +export const serverSchema = z.object({ + // DATABASE_URL: z.string().url(), +}); + +export const clientSchema = z.object({ + // NEXT_PUBLIC_WS_KEY: z.string(), +}); + +export const clientEnv = { + // NEXT_PUBLIC_WS_KEY: process.env.NEXT_PUBLIC_WS_KEY, +}; +``` + +### Server Schema + +Define your server-side environment variables schema here. + +Make sure you do not prefix keys here with `NEXT_PUBLIC`. Validation will fail if you do to help you detect invalid configuration. + +### Client Schema + +Define your client-side environment variables schema here. + +To expose them to the client you need to prefix them with `NEXT_PUBLIC`. Validation will fail if you don't to help you detect invalid configuration. + +### clientEnv Object + +Destruct the `process.env` here. + +We need a JavaScript object that we can parse our Zod-schemas with and due to the way Next.js handles environment variables, you can't destruct `process.env` like a regular object, so we need to do it manually. + +TypeScript will help you make sure that you have entered the keys in both `clientEnv` as well as `clientSchema`. + +```ts +// ❌ This doesn't work, we need to destruct it manually +const schema = z.object({ + NEXT_PUBLIC_WS_KEY: z.string(), +}); + +const validated = schema.parse(process.env); +``` + +## server.mjs & client.mjs + +This is where the validation happens and exports the validated objects. You shouldn't need to modify these files. + +## Using Environment Variables + +When you want to use your environment variables, you can import them from `env/client.mjs` or `env/server.mjs` depending on where you want to use them: + +```ts:pages/api/hello.ts +import { env } from "../../env/server.mjs"; + +// `env` is fully typesafe and provides autocompletion +const dbUrl = env.DATABASE_URL; +``` + +## .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` + +📄 `schema.mjs`: Add the appropriate validation logic for the environment variable by defining a Zod schema, e.g. `KEY: z.string()` + +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 `schema.mjs`: + +```ts +export const serverSchema = z.object({ + // ... + TWITTER_API_TOKEN: z.string(), +}); +``` + +_**NOTE:** An empty string is still a string, so `z.string()` will accept an empty string as a valid value. If you want to make sure that the environment variable is not empty, you can use `z.string().min(1)`._ + +3. optional: Add the environment variable to `.env.example`, but don't include the token + +``` +TWITTER_API_TOKEN= +``` diff --git a/www/src/pages/tr/usage/first-steps.md b/www/src/pages/tr/usage/first-steps.md new file mode 100644 index 0000000000..d2f4b244f6 --- /dev/null +++ b/www/src/pages/tr/usage/first-steps.md @@ -0,0 +1,36 @@ +--- +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 + +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 after doing this so that it can detect the generated types. + +## 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. + +## Next Steps + +- If your app includes tRPC, check out `src/pages/index.tsx` and `src/server/trpc/router/example.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/tr/usage/index.astro b/www/src/pages/tr/usage/index.astro new file mode 100644 index 0000000000..b12c75e6be --- /dev/null +++ b/www/src/pages/tr/usage/index.astro @@ -0,0 +1,24 @@ +--- +import Layout from "../../../layouts/docs.astro"; +import IndexPage from "../../../components/docs/indexPage.astro"; +import { Frontmatter, SIDEBAR } from "../../../config"; +import { getLanguageFromURL } from "../../../languages"; + +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/tr/usage/next-auth.md b/www/src/pages/tr/usage/next-auth.md new file mode 100644 index 0000000000..27b21bac5c --- /dev/null +++ b/www/src/pages/tr/usage/next-auth.md @@ -0,0 +1,175 @@ +--- +title: NextAuth.js +description: Usage of NextAuth.js +layout: ../../../layouts/docs.astro +lang: en +--- + +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}!

; +}; +``` + +## 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:pages/api/auth/[...nextauth].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:types/next-auth.d.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 [`unstable_getServerSession`](https://next-auth.js.org/configuration/nextjs#unstable_getserversession) function. Don't worry, this function is safe to use - the name includes `unstable` only because the API implementation might change in the future. The advantage of using `unstable_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. + +```ts:server/common/get-server-auth-session.ts +export const getServerAuthSession = async (ctx: { + req: GetServerSidePropsContext["req"]; + res: GetServerSidePropsContext["res"]; +}) => { + return await unstable_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/trpc/context.ts +import { getServerAuthSession } from "../common/get-server-auth-session"; + +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/trpc/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/trpc/router/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://next-auth.js.org/adapters/models/). `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. + +## 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/tr/usage/next-js.md b/www/src/pages/tr/usage/next-js.md new file mode 100644 index 0000000000..e88a8613af --- /dev/null +++ b/www/src/pages/tr/usage/next-js.md @@ -0,0 +1,35 @@ +--- +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. + +## 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/tr/usage/prisma.md b/www/src/pages/tr/usage/prisma.md new file mode 100644 index 0000000000..e575e997cf --- /dev/null +++ b/www/src/pages/tr/usage/prisma.md @@ -0,0 +1,77 @@ +--- +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 `/server/db/client.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#-servertrpccontextts) 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/client"; + +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 | +| 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/tr/usage/tailwind.md b/www/src/pages/tr/usage/tailwind.md new file mode 100644 index 0000000000..bdb355a4b0 --- /dev/null +++ b/www/src/pages/tr/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/tr/usage/trpc.md b/www/src/pages/tr/usage/trpc.md new file mode 100644 index 0000000000..9085d25f99 --- /dev/null +++ b/www/src/pages/tr/usage/trpc.md @@ -0,0 +1,324 @@ +--- +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 front- 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 + +
+
+
+ +## 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/trpc/context.ts` + +This file is where you 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. + +- `createContextInner`: 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. + +- `createContext`: 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 `createContextInner` function to create the final context. + +### 📄 `server/trpc/trpc.ts` + +This is where you 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/trpc/router/*.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, then [merge](https://trpc.io/docs/v10/merging-routers) all of them into a single app router in `server/trpc/router/_app.ts`. + +### 📄 `utils/trpc.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. + +## 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/trpc/router/user.ts +const userRouter = t.router({ + getById: t.procedure.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/trpc/router/_app.ts +const appRouter = t.router({ + 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"; + +const UserPage = () => { + const { query } = useRouter(); + const userQuery = trpc.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 `trpc.`, 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. + +## 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, NextApiResponse } from "next"; +import { appRouter } from "../../../server/trpc/router/_app"; +import { createContext } from "../../../server/trpc/context"; + +const userByIdHandler = async (req: NextApiRequest, res: NextApiResponse) => { + // Create context and caller + const ctx = await createContext({ 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, NextApiResponse } from "next"; +import { prisma } from "../../../server/db/client"; + +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, NextApiResponse } from "next"; +import { createNextApiHandler } from "@trpc/server/adapters/next"; +import { appRouter } from "~/server/trpc/router/_app"; +import { createContext } from "~/server/trpc/context"; +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, + })(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 = trpc.post.list.useQuery(); + + const utils = trpc.useContext(); + const postCreate = trpc.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 { createContextInner } from "~/server/router/context"; +import { appRouter, type AppRouter } from "~/server/router/_app"; +import { expect, test } from "vitest"; + +test("example router", async () => { + const ctx = await createContextInner({ 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" }); +}); +``` + +## 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/tr/usage/typescript.md b/www/src/pages/tr/usage/typescript.md new file mode 100644 index 0000000000..833fd5b2bc --- /dev/null +++ b/www/src/pages/tr/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/tr/why.md b/www/src/pages/tr/why.md new file mode 100644 index 0000000000..87bb204ef7 --- /dev/null +++ b/www/src/pages/tr/why.md @@ -0,0 +1,50 @@ +--- +title: Neden CT3A? +description: Bir sonraki projeniz için neden Create T3 App kullanmalısınız +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.