diff --git a/.changeset/calm-stingrays-end.md b/.changeset/calm-stingrays-end.md new file mode 100644 index 0000000000..29b392a12b --- /dev/null +++ b/.changeset/calm-stingrays-end.md @@ -0,0 +1,6 @@ +--- +"create-t3-app": patch +"@ct3a/www": patch +--- + +fix(t3-app): fix broken links diff --git a/cli/template/addons/trpc/auth-router.ts b/cli/template/addons/trpc/auth-router.ts index aa083d154e..0fd218518d 100644 --- a/cli/template/addons/trpc/auth-router.ts +++ b/cli/template/addons/trpc/auth-router.ts @@ -5,6 +5,6 @@ export const authRouter = router({ return ctx.session; }), getSecretMessage: protectedProcedure.query(() => { - return "you can see this secret message!"; + return "you can now see this secret message!"; }), }); diff --git a/cli/template/base/src/pages/index.tsx b/cli/template/base/src/pages/index.tsx index 835590d790..cbfff1a91b 100644 --- a/cli/template/base/src/pages/index.tsx +++ b/cli/template/base/src/pages/index.tsx @@ -17,14 +17,20 @@ const Home: NextPage = () => { Create T3 App
- +

First Steps →

Just the basics - Everything you need to know to set up your database and authentication.
- +

Documentation →

Learn more about Create T3 App, the libraries it uses, and how diff --git a/cli/template/page-studs/index/with-auth-trpc.tsx b/cli/template/page-studs/index/with-auth-trpc.tsx index 1d8509e43e..9510359cd3 100644 --- a/cli/template/page-studs/index/with-auth-trpc.tsx +++ b/cli/template/page-studs/index/with-auth-trpc.tsx @@ -22,14 +22,20 @@ const Home: NextPage = () => { Create T3 App
- +

First Steps →

Just the basics - Everything you need to know to set up your database and authentication.
- +

Documentation →

Learn more about Create T3 App, the libraries it uses, and how diff --git a/cli/template/page-studs/index/with-trpc.tsx b/cli/template/page-studs/index/with-trpc.tsx index 357daed6d6..e7b9d82e82 100644 --- a/cli/template/page-studs/index/with-trpc.tsx +++ b/cli/template/page-studs/index/with-trpc.tsx @@ -21,14 +21,20 @@ const Home: NextPage = () => { Create T3 App
- +

First Steps →

Just the basics - Everything you need to know to set up your database and authentication.
- +

Documentation →

Learn more about Create T3 App, the libraries it uses, and how diff --git a/www/src/components/landingPage/stack/stack.astro b/www/src/components/landingPage/stack/stack.astro index 16b5c10342..c7cda5f8a4 100644 --- a/www/src/components/landingPage/stack/stack.astro +++ b/www/src/components/landingPage/stack/stack.astro @@ -63,7 +63,7 @@ import Feature from "./card.astro"; Prisma is the best way to work with databases in TypeScript. It provides a simple, type-safe API to query your database, and it can - be used with most SQL dialects (and Mongo too!) + be used with most SQL dialects (and Mongo too!). @@ -129,7 +129,7 @@ import Feature from "./card.astro"; If your frontend and backend are TypeScript, it's really hard to beat the DX of tRPC. Kinda like GraphQL but without the work - - seriously this lib is magic + seriously this lib is magic. diff --git a/www/src/pages/en/deployment/vercel.md b/www/src/pages/en/deployment/vercel.md index 121580637b..f9bfe4a42a 100644 --- a/www/src/pages/en/deployment/vercel.md +++ b/www/src/pages/en/deployment/vercel.md @@ -8,7 +8,7 @@ We recommend deploying your app to [Vercel](https://vercel.com/?utm_source=t3-os ## Project Configuration -Vercel will likely configure your build command and publish directory automatically. However, you can also specify this information along with other configuration by creating a file called [`vercel.json`](https://vercel.com/docs/project-configuration) and including the following commands: +Vercel will likely configure your build command and publish the directory automatically. However, you can also specify this information along with other configurations by creating a file called [`vercel.json`](https://vercel.com/docs/project-configuration) and including the following commands: ```json { diff --git a/www/src/pages/en/faq.md b/www/src/pages/en/faq.md index 910b218b64..a7a37dc938 100644 --- a/www/src/pages/en/faq.md +++ b/www/src/pages/en/faq.md @@ -15,7 +15,7 @@ If you are not familiar with the different technologies used in this project, pl - [Next.js](https://nextjs.org/) - [NextAuth.js](https://next-auth.js.org) - [Prisma](https://prisma.io) -- [TailwindCSS](https://tailwindcss.com) +- [Tailwind CSS](https://tailwindcss.com) - [tRPC](https://trpc.io) ## What learning resources are currently available? diff --git a/www/src/pages/en/other-recs.md b/www/src/pages/en/other-recs.md index fc59d72f4b..a649c5fea5 100644 --- a/www/src/pages/en/other-recs.md +++ b/www/src/pages/en/other-recs.md @@ -25,7 +25,7 @@ The "modern, simple Redux" you didn't know you needed. [Poimandres](https://gith **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. Great option for stateful behaviors that don't need a state machine just yet. +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) @@ -36,7 +36,7 @@ Most apps need the same handful of components - toggle buttons, dropdown menus, ### 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. +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. @@ -99,7 +99,7 @@ Vercel took the hell of web deployments and made it a set-and-forget GitHub inte **For databases without the worry** -PlanetScale is the best "serverless database platform" we've used by far. Insane scale, great developer experience, fantastic pricing. If you're using SQL (and hopefully Prisma), this is hard to beat. +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/) @@ -107,7 +107,7 @@ PlanetScale is the best "serverless database platform" we've used by far. Insane **For hosting your infra** -"Modern Heroku". 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. +"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/) @@ -129,7 +129,7 @@ If WebSockets are the primary focus of your project, you may want to consider a ### Soketi -Soketi is an 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 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) diff --git a/www/src/pages/en/usage/env-variables.md b/www/src/pages/en/usage/env-variables.md index be7f08bd13..b87b97d8cb 100644 --- a/www/src/pages/en/usage/env-variables.md +++ b/www/src/pages/en/usage/env-variables.md @@ -16,7 +16,7 @@ Create-T3-App uses [Zod](https://github.com/colinhacks/zod) for validating your 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 defining the validator in `env/schema.mjs`._ +_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 @@ -40,7 +40,7 @@ export const clientEnv = { Define your server-side environment variables schema here. -Make sure you do not prefix keys in here with `NEXT_PUBLIC`. Validation will fail if you do to help you detect invalid configuration. +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 @@ -88,7 +88,7 @@ Since the default `.env` file is not committed to version control, we have also 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 environement variable like you would normally do in a `.env` file, i.e. `KEY=VALUE` +📄 `.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()` diff --git a/www/src/pages/en/usage/next-auth.md b/www/src/pages/en/usage/next-auth.md index 52eb560f91..3b14c973ac 100644 --- a/www/src/pages/en/usage/next-auth.md +++ b/www/src/pages/en/usage/next-auth.md @@ -4,7 +4,7 @@ description: Usage of NextAuth.js layout: ../../../layouts/docs.astro --- -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. +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 @@ -70,7 +70,7 @@ When using NextAuth.js with tRPC, you can create reusable, protected 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 its 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. +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: { @@ -134,9 +134,9 @@ Getting NextAuth.js to work with Prisma requires a lot of [initial setup](https: ### 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. +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: +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 { diff --git a/www/src/pages/en/usage/prisma.md b/www/src/pages/en/usage/prisma.md index 983c92996b..d2b5b03cd8 100644 --- a/www/src/pages/en/usage/prisma.md +++ b/www/src/pages/en/usage/prisma.md @@ -16,11 +16,11 @@ You will find the Prisma schema file at `/prisma/schema.prisma`. This file is wh ### 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). +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 a SQLite database, which is great for development and quickly spinning up a proof-of-concept, but 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. +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 diff --git a/www/src/pages/en/usage/trpc.md b/www/src/pages/en/usage/trpc.md index 42cbb3f976..8e68853c18 100644 --- a/www/src/pages/en/usage/trpc.md +++ b/www/src/pages/en/usage/trpc.md @@ -38,7 +38,7 @@ tRPC requires quite a lot of boilerplate that `create-t3-app` sets up for you. L ### 📄 `pages/api/trpc/[trpc].ts` -This is the entrypoint 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?retiredLocale=sv-SE) 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. +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?retiredLocale=sv-SE) 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` @@ -50,9 +50,9 @@ This file is where you define the context that is passed to your tRPC procedures ### 📄 `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. +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. +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` @@ -60,7 +60,7 @@ This is where you define the routes and procedures of your API. By convention, y ### 📄 `utils/trpc.ts` -This is the frontend entrypoint 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. +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. @@ -88,11 +88,11 @@ const userRouter = t.router({ }); ``` -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. +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. +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`: +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({ @@ -220,7 +220,7 @@ Compare this to the tRPC example above and you can see some of the advantages of - 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 doesn't provide and autocompletion or type safety. +- Calling the procedure on the frontend doesn't provide any autocompletion or type safety. ## Useful snippets @@ -253,7 +253,7 @@ 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). +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 = () => {