Home > Article > Web Front-end > Building a Kanban Board with Next.js,Vercel AI and Tolgee
In this article, we will build a real-time Kanban board in Next.js using WebSockets, with database support, AI support through the Vercel AI SDK and localization via Tolgee.
What You Will Learn: ✨
Star the Tolgee repository ⭐
Are you ready to build a unique Kanban board with AI and localization support? ?
Initialize a new Next.js application with the following command:
ℹ️ You can use any package manager of your choice. For this project, I will use npm.
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
Next, navigate into the newly created Next.js project:
cd kanban-ai-realtime-localization
We’ll need several dependencies. Run this command to install all the dependencies required for our project:
npm install @ai-sdk/openai @tolgee/react @tolgee/web @tolgee/format-icu @tanstack/react-query @prisma/client ai socket.io socket.io-client prisma next-auth date-fns nodemon ts-node zod tsconfig-paths react-beautiful-dnd
For UI components, we will use shadcn/ui. Initialize it with default settings with this command:
npx shadcn@latest init -d
Now, let’s add some UI components that we are going to use in our application later on. To add reusable components from shadcn/ui, run this command:
npx shadcn@latest add button card input label select textarea toast
Inside the app/components/ui directory, some additional files will be added for these components, which we will use when building the UI for our application.
Initialize Prisma with the following command:
npx prisma init
After you run this command, a new schema.prisma file should be created in the prisma directory at the root of your project.
Modify the newly created schema.prisma file to use PostgreSQL as the database and include the User and Task models.
// ? prisma/schema.prisma // This is your Prisma schema file, // learn more about it in the docs: <https://pris.ly/d/prisma-schema> // Looking for ways to speed up your queries, or scale easily with your serverless or edge functions? // Try Prisma Accelerate: <https://pris.ly/cli/accelerate-init> generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model User { id String @id @default(cuid()) email String @unique password String tasks Task[] @relation("UserTasks") createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model Task { id String @id @default(cuid()) title String description String? userId String column Int order Int createdBy User @relation("UserTasks", fields: [userId], references: [id]) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt }
The model is straightforward: each user can have multiple tasks, with each task linked to a specific user. A task has an integer column value representing its status (0 for ongoing, 1 for pending, and 2 for completed). The order value determines each task's position within its assigned column.
Now that we have our model ready, we need to push it to our database. For this, we need the connection URL.
If you already have access to a database with Neon or another service, that's great. Populate the .env file with the connection URL. You don't need to set up the database locally with docker.
If you're following along and just want to try the project with a local PostgreSQL database using Docker, add a new variable named DATABASE_URL with this connection string value to the .env file.
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
To run a database locally, make sure you have Docker installed. Create a new directory named scripts in the root of the project and add a file called start-local-db-docker.sh with the following lines of code:
cd kanban-ai-realtime-localization
This script basically reads the .env file for the DATABASE_URL variable and extracts all the relevant data like the username, password, the database name and creates a container if it does not exist. If it already does, it simply spins up the existing container.
Run this script to create and run a PostgreSQL container which will host all the user data for our application.
npm install @ai-sdk/openai @tolgee/react @tolgee/web @tolgee/format-icu @tanstack/react-query @prisma/client ai socket.io socket.io-client prisma next-auth date-fns nodemon ts-node zod tsconfig-paths react-beautiful-dnd
Now, we should have a running container with PostgreSQL. You can check if that is the case by running this command:
npx shadcn@latest init -d
Now, we will need a way to instantiate a Prisma client to interact with the database.
Create a new file index.ts inside the src/db directory and add the following lines of code:
npx shadcn@latest add button card input label select textarea toast
We set up a singleton instance of the PrismaClient to ensure only one instance is created and reused across your application, especially helpful in development mode.
We can now use our exported constant db to interact with our database in our application.
Run the following command to push your changes in your schema to the database.
npx prisma init
Now, to have the updated types work in the IDE, run the following command to generate new types based on our updated schema.
// ? prisma/schema.prisma // This is your Prisma schema file, // learn more about it in the docs: <https://pris.ly/d/prisma-schema> // Looking for ways to speed up your queries, or scale easily with your serverless or edge functions? // Try Prisma Accelerate: <https://pris.ly/cli/accelerate-init> generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model User { id String @id @default(cuid()) email String @unique password String tasks Task[] @relation("UserTasks") createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model Task { id String @id @default(cuid()) title String description String? userId String column Int order Int createdBy User @relation("UserTasks", fields: [userId], references: [id]) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt }
This is all that we need to set up our application database. ?
To enable localization in your Next.js application with Tolgee, follow these steps:
This file handles language detection and cookie management.
// ? .env # If you are using local DB with docker DATABASE_URL=postgresql://postgres:password@localhost:5432/kanban-board
The setLanguage function saves the selected language (locale) as a cookie with a one-year expiry, allowing the app to remember the user's language preference across sessions.
The getLanguage function checks for the saved language in cookies. If a valid language is found, it returns that; otherwise, it attempts to detect the language from the browser's headers if running in a browser. If detection fails or the environment isn't a browser, it defaults to DEFAULT_LANGUAGE.
This file contains shared constants and functions for handling localization, including fetching static data for translations
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
The getStaticData function is responsible for loading translations for specific languages and namespaces to prefetch localized content. It fetches JSON files from messages directory, by language and namespace, and then bundles everything into a single object and returns it.
For language selection in our application, we will provide the user with four different language choices (English, Czech, French and German). You can add support to other languages if you like.
Inside the messages directory at the root of the project, we will store different static data for different words and sentences.
ℹ️ You can find link to these static translation file in my repository. There is nothing to explain in that file as they are bunch of translation sentences in different other languages.
The TolgeeBase function sets up Tolgee with tools for handling translations. It adds support for ICU message formatting (FormatIcu) and includes DevTools for debugging. The function uses the API key and URL from environment variables and sets English (en) as the fallback language.
We are using two different env variables, populate the .env file with these API keys. Sign up for an account in Tolgee and get access to the TOLGEE_API_KEYS, but for this application, it is not required to have that API key.
cd kanban-ai-realtime-localization
This file configures the Tolgee instance for server-side rendering, setting up translation handling.
npm install @ai-sdk/openai @tolgee/react @tolgee/web @tolgee/format-icu @tanstack/react-query @prisma/client ai socket.io socket.io-client prisma next-auth date-fns nodemon ts-node zod tsconfig-paths react-beautiful-dnd
This code creates a Tolgee instance for server-side translation handling. It starts by setting getLocale to use the getLanguage function, which retrieves the user’s preferred language. Then, in createTolgee, it initializes Tolgee with translation data for all supported languages through getStaticData.
It also sets Tolgee to use the provided language (from getLanguage) and configures a custom fetch function to always load fresh data by setting revalidate: 0, preventing caching of translation requests.
This sets up the Tolgee provider for client-side rendering.
npx shadcn@latest init -d
This code sets up a client-side Tolgee provider for translations. TolgeeProviderClient takes language, staticData, and children as props, and it initializes Tolgee with the specified language and data. Inside useEffect, it listens for language changes with permanentChange, refreshing the page through router.refresh() whenever the language updates.
Finally, TolgeeProvider renders the children, using ssr options to preload translations and displaying "Loading..." if translations aren’t ready instantly.
Finally, wrap your application with the
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
Here first we are getting access to the locale of the user based on the header or from the cookie which we set from the function. Then we provide that locale to the
tag.That is all we need to set up Tolgee in our Next.js application. ✨This is going to be a standard process that you need to do to implement location with Tolgee in any Next.js applications.
We will be using NextAuth for authentication in our application. First, let’s start by defining a new Zod schema which we will use to validate the user-passed data.
Define a Zod schema (AuthSchema) to validate user input for email and password during login and registration. This ensures the email format is correct and the password meets specified length requirements.
cd kanban-ai-realtime-localization
We require the email field to be the exact email and not any other string and we want the password field to be a minimum length of 8 characters and a max length of 20 characters. We will use this validation schema in multiple places to validate the user-passed data in our login/register form to check if it meets the criteria.
You set up NextAuth in route.ts under src/app/api/auth/[...nextauth], using CredentialsProvider for authentication. The authorize function validates the credentials, checks the user's existence, and verifies the password.
npm install @ai-sdk/openai @tolgee/react @tolgee/web @tolgee/format-icu @tanstack/react-query @prisma/client ai socket.io socket.io-client prisma next-auth date-fns nodemon ts-node zod tsconfig-paths react-beautiful-dnd
The authorize function logic is responsible for logging in the user or not. The function in this setup checks if the provided email and password match an existing user in the database.
We are using only the Credential based authentication. First, it validates the credentials using the AuthSchema for field validation. If validation succeeds, it looks up the user by email in the database. If the user is found, it then compares the hashed password in the database with the password input. If both checks pass, it returns the user's data (excluding the password).
As you might have guessed, here we require NEXTAUTH_SECRET variable to be defined inside the .env file. Populate the .env file with these two variables:
npx shadcn@latest init -d
In the src/app/api/auth/register/route.ts, we create an endpoint for user registration that hashes the password and stores user data in the database. We then return appropriate responses based on validation success.
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
Here, we parse the data received from the client and validate it with the AuthSchema we wrote earlier. Then, we create a hash with a rotation value of 12. This generates an encrypted text that we will store in our database, and finally, we return the user.
Now to make our application a lot solid, let’s add a middleware that checks for the userSession anytime a user visits a certain route, and if they are not authenticated they are not allowed to visit that route.
We add a middleware to restrict access to the /kanban route for unauthenticated users.
cd kanban-ai-realtime-localization
Here, we are saying that a user should not be able to visit the “/kanban” route if they are not authenticated.
We are done with the backend logic for handling authentication. Let’s work on some client-side logic.
Our Navbar component is going to be comprised of some smaller components as well. We will have a button to login, register, logout and a select tag to allow the user to switch languages.
Let’s begin working on these components!
Inside the src/app/components directory create a new file lang-selector.tsx with the following lines of code:
npm install @ai-sdk/openai @tolgee/react @tolgee/web @tolgee/format-icu @tanstack/react-query @prisma/client ai socket.io socket.io-client prisma next-auth date-fns nodemon ts-node zod tsconfig-paths react-beautiful-dnd
The component should be pretty self-explanatory. We are using the component provided by shadcn/ui to map on all the available language choices we have. Based on the user selection, we set the language to that with the setLanguage function we worked on in language.ts file earlier.
? NOTE: Notice how we are not hardcoding any text in the code; instead, we are using components from Tolgee to render the text. This way, when the user switches the language, the text changes accordingly. If we hardcoded the text, implementing translations would be ineffective. We will continue using this approach moving forward.
We are using the
Similarly, Inside this components directory create a new file called logout-btn.tsx with the following lines of code:
npx shadcn@latest init -d
Similar to earlier, when the user clicks on the Button, we trigger the handleLogout function which then tries to log out the user and if any error is occured, it then shows a toast notification with the translated error message.
We use our loading state to display a loader icon when logging out the user.
Finally, now that both of the smaller components that we required are available, let’s work on the
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
This Navbar component creates a navigation bar for our application. It checks if a user is logged in using getServerSession. If the user is authenticated, a logout button is shown. If not, it shows the link to the user to login and register.
Now, that we are done with handling the backend logic for authentication and also done implementing Tolgee to our application. Let’s work on some client-side logic and build some UI.
Inside the app/components directory, create a new file login.tsx with the following lines of code:
cd kanban-ai-realtime-localization
This Login component displays a login form for email and password, with both input fields functioning as controlled components. Upon form submission, it calls signIn from next-auth to handle authentication. If the login fails, a translated error message is displayed via a toast notification. Successful logins redirect the user to the homepage.
We also have a separate loading state variable, which we use to show a loading animation icon while logging the user into our application.
Currently, this is just a component we have created; it is not yet displayed in our application. To do that, we need to render this component in the app directory of our application.
Inside the src/app/login directory, create a new file called page.tsx with the following lines of code:
npm install @ai-sdk/openai @tolgee/react @tolgee/web @tolgee/format-icu @tanstack/react-query @prisma/client ai socket.io socket.io-client prisma next-auth date-fns nodemon ts-node zod tsconfig-paths react-beautiful-dnd
In the login page, we first check if the user has an active session. If the user has an active session, we simply redirect them to the “/kanban” route (which we will implement shortly). If the user does not have an active session, we display the earlier
We have now completed the implementation of the Login page; similarly, let’s build the Register page.
Inside the app/components directory, create a new file register.tsx with the following lines of code:
npx shadcn@latest init -d
The email and password inputs in this component function as controlled components, similar to those on the login page. Here, we use React Query to simplify the process of making the POST request. This approach eliminates the need to manage separate states for loading or error handling.
When the user clicks the submit button in the form, a POST request is made to our API route for registering a user in the database we worked on earlier. If the registration succeeds, the user is redirected to the login page. If not, a toast message is displayed with the translated error message.
When the user clicks the submit button, a POST request is sent to our API route to register the user in the database we previously set up. Upon successful registration, the user is redirected to the login page. If the registration fails, we display a toast message with the translated error message using the relevant keys.
Inside the src/app/register directory, create a new file called page.tsx with the following lines of code:
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
With this page set up, we have completed the authentication flow of our application. You should now have a working authentication-enabled application with localization support.
In this section, we will set up a WebSocket server for our application. Let’s first create a function that helps us get access to the socket.
Inside the src/config directory, create a new file socket.ts with the following lines of code:
cd kanban-ai-realtime-localization
This code defines a function getSocket that initializes a Socket.IO client connection to the URL specified in the environment variable NEXT_PUBLIC_APP_URL, ensuring that the socket is created only once. If the socket is already initialized, it simply returns the existing socket instance.
Now, we need to manage our socket.io connection and provide a way for our components to access the socket instance. Inside the src/providers directory, create a new file socket-provider.tsx with the following lines of code:
npm install @ai-sdk/openai @tolgee/react @tolgee/web @tolgee/format-icu @tanstack/react-query @prisma/client ai socket.io socket.io-client prisma next-auth date-fns nodemon ts-node zod tsconfig-paths react-beautiful-dnd
This code creates a React context for managing a Socket.IO connection, providing a useSocket hook to access the socket instance. The SocketProviderClient initializes the socket using the getSocket function and connects it, then wraps its children in a context provider to share the socket instance throughout the application.
Now, we need to wrap our application with this socket provider to get access to using WebSocket for sending and receiving data.
Inside the same directory, create a new file providers.tsx which we will use to wrap our child components with the QueryClientProvider from @tanstack/react-query and our newly created SocketProviderClient.
Add the following lines of code to the file:
npx shadcn@latest init -d
Now, all we need to do is, wrap our application with this
Modify the layout.tsx in the root of the project with the following lines of code:
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
Now, we are ready to create our own Socket.io server. Create a new file server.ts and add the following lines of code:
cd kanban-ai-realtime-localization
Now, this server.ts file becomes the entry point to our application. We can do almost anything we would do with a socket.io server with a backend framework like express.js.
We can now listen for any events similar to listening for ‘connection’ and ‘disconnect’ here. We will modify this file in the future to listen to our custom events.
Now, create a new file tsconfig.server.json which will hold settings specific to our server. Add the following lines of code:
npm install @ai-sdk/openai @tolgee/react @tolgee/web @tolgee/format-icu @tanstack/react-query @prisma/client ai socket.io socket.io-client prisma next-auth date-fns nodemon ts-node zod tsconfig-paths react-beautiful-dnd
This tsconfig.server.json file extends the base TypeScript configuration found in tsconfig.json and specifies some custom settings for our project. It uses CommonJS for module output, and directs compiled files to the dist directory. The isolatedModules option is set to false, permitting files that may not be self-contained, while noEmit is false, allowing output files to be generated. Finally, it includes only the server.ts file in the compilation process.
For our development server, we will be using nodemon and also now we are using server.ts file as our server. So, modify the scripts in the package.json file to this:
npx shadcn@latest init -d
Also, we need to tweak the nodemon configuration to watch changes in the server.ts file and change its execution command.
Create a new file nodemon.json in the root of the project with the following configuration:
npx shadcn@latest add button card input label select textarea toast
Finally, now we are done with all the pre-works for our board. Let’s work on displaying and creating tasks for our board.
Inside the src/components directory, create a new file task.tsx with the following lines of code:
npx prisma init
We will use this to display tasks in our application. Here, we are essentially accepting a task object as a prop and using the Card component to present the task content in a card-like fashion. We are using the date-fns package to format the date in a more readable manner.
Now, let’s create a component that we can use to add tasks to our board. Inside the src/components directory, create a new file add-task.tsx with the following lines of code:
// ? prisma/schema.prisma // This is your Prisma schema file, // learn more about it in the docs: <https://pris.ly/d/prisma-schema> // Looking for ways to speed up your queries, or scale easily with your serverless or edge functions? // Try Prisma Accelerate: <https://pris.ly/cli/accelerate-init> generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model User { id String @id @default(cuid()) email String @unique password String tasks Task[] @relation("UserTasks") createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model Task { id String @id @default(cuid()) title String description String? userId String column Int order Int createdBy User @relation("UserTasks", fields: [userId], references: [id]) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt }
This component has a lot going on. There are two input fields, both of which are controlled components. However, the textarea is set to readOnly since it’s meant to be populated by the AI rather than by the user. We use two state variables, title, and description, to manage the title and description fields.
When the user clicks the submit button, an API request is made to our task creation endpoint, which adds a new task for the user in the database and returns it. If any errors occur, a toast displays the translated error message. Upon success, we reset the input fields and emit an event that the server will pick up, triggering an update on the board component to display all tasks.
The useChat hook, accessed from Vercel's AI SDK, is particularly interesting here. It provides access to fields like the message history and the current input message, along with the isPending variable, which tracks whether the AI’s response is still loading.
When the user clicks the Generate button, we submit the title to the AI. Once we receive a response, we check the messages field using the useEffect hook. If the assistant’s message updates, we set the description to this new message.
Now, we will update the server.ts file to also listen for the task-created event. Modify the server.ts file in the root of the project with the following lines of code:
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
Here, we listen for that event, and once it is received, we emit it to all the connected sockets. It is then received by the
Now, in our
Let’s create a schema file for validation of the input from the user and the AI. Inside the src/lib/validators directory, create a new file message.ts with the following lines of code:
cd kanban-ai-realtime-localization
Now, we can use these schemas to infer the type of response from the AI to get type validation in our API route.
Finally, Inside the src/api/chat directory, create a new file route.ts with the following lines of code:
npm install @ai-sdk/openai @tolgee/react @tolgee/web @tolgee/format-icu @tanstack/react-query @prisma/client ai socket.io socket.io-client prisma next-auth date-fns nodemon ts-node zod tsconfig-paths react-beautiful-dnd
In this API route, we start by validating the input to ensure it includes a messages array where each object has a role and content field. Next, we extract the latest user message (i.e., the most recent question or request to the AI) from this array. With this message in hand, we pass it to the streamText function, prompting the AI to generate a task description based on the message content.
Finally, we return the response as a data stream, allowing the client to update the messages array in real-time. This streaming response triggers the useEffect hook, which updates the description field, displaying the AI-generated description directly in the text area.
Inside the src/lib/validators directory, create a new file create-task.ts with the following lines of code:
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
The CreateTaskSchema schema defines the structure for creating a task. It requires a title between 1 and 50 characters and includes an optional description.
The inferred type, TCreateTaskSchema, provides type safety for this structure, allowing us to use it for consistent typing in both client-side and server-side code.
Now, let’s work on the task creation endpoint, i.e. /api/tasks/[userId]/create.
Create a new directory with this path and create a route.ts inside the file with the following lines of code:
cd kanban-ai-realtime-localization
This API route creates a new task. It first checks for a valid user session with getServerSession. If there is no active session (the user is not logged in), it returns a 401 Unauthorized error. Next, it validates the request body with CreateTaskSchema, and if validation fails, it responds with a 422 status and error details.
If the input is valid, it counts tasks in the default column (0 - ongoing) for ordering, then creates a new task in the database with the provided title, optional description, user ID, column, and order value, which is the length of the array. The new task is returned on success; otherwise, it returns an Internal Server Error.
? Here, we will build the main UI components and some APIs for updating tasks on our Board
Now, let’s create a
Inside the src/components directory, create a new file board.tsx with the following lines of code:
npm install @ai-sdk/openai @tolgee/react @tolgee/web @tolgee/format-icu @tanstack/react-query @prisma/client ai socket.io socket.io-client prisma next-auth date-fns nodemon ts-node zod tsconfig-paths react-beautiful-dnd
This is the component where we will be utilizing the main feature of a Kanban board, i.e., drag-and-drop items. For this, we will use our previously installed package, react-beautiful-dnd. The component first fetches the user session using getSession and sets it in the state. Once the session is available, it makes an API call to fetch tasks for the logged-in user and stores them in tasks.
It listens for two-socket events —tasks-updated, which updates the task list, and task-created, which appends a new task to the current task list.
Tasks are grouped by column status (0 for "Ongoing," 1 for "Pending," and 2 for "Completed") using the tasksByStatus function. The component maps these statuses to render each column with the corresponding tasks.
The DragDropContext wrapper enables drag-and-drop functionality. When a task is moved, handleDragEnd sends the new task order to the server via a socket event for syncing.
Each column is a Droppable area that contains draggable Task components, allowing users to reorder tasks within and across columns.
Now, let’s work on the /api/tasks route which is responsible for returning a list of user tasks from the database.
Inside the app/api/tasks, create a route.ts file with the following lines of code:
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
The GET function in this API route fetches a user's information, including their tasks. It starts by validating the authentication using getServerSession. If the session is absent, a 401 Unauthorized status is returned.
The route extracts the email and userId from the request URL's query parameters. If the userId is missing or the session's user email does not match the provided email, a 403 Forbidden status is returned.
Next, it queries the database for a user with the specified email and ID, selecting only the user's ID and tasks. If no user is found, a 404 Not Found status is returned. If the user exists, their data is sent in the response.
Now, we are almost done; we just need to listen for the task-drag event from the
Modify the server.ts file in the root of the project with the following lines of code:
cd kanban-ai-realtime-localization
The task-drag event is responsible for handling the drag-and-drop functionality of tasks within your Kanban board. When a task is dragged from one position to another, this event is triggered, allowing the server to update the task's status and position in the database.
When a client emits the 'task-drag' event, it sends a payload containing the source and destination locations of the task being dragged, as well as the user's email address. The server listens for this event.
The server then calls the handleTaskDrag function, passing the user's email, the source, and the destination as arguments. This function is responsible for fetching the user from the database using their email address, ensuring that the task updates are associated with the correct user.
Within handleTaskDrag, the function retrieves the user's tasks from the database and then calls updateTasksInDB, which processes the task update logic. This function updates the column and order of the task based on the drag-and-drop operation, ensuring that the tasks are rearranged correctly in the database.
If the tasks are updated successfully, the updated tasks are emitted back to all connected clients using io.sockets.emit, broadcasting the changes so that the user interface can be updated in real time.
Now that we have both the
Inside the src/app/kanban directory, create a new file page.tsx with the following lines of code:
npx create-next-app@latest kanban-ai-realtime-localization --typescript --tailwind --eslint --app --src-dir --use-npm
It starts by checking the user's session with getServerSession, redirecting to the login page if the session is absent. This statement is probably never going to execute because we built a middleware.ts file earlier in the src directory, which states that any route starting with /kanban cannot be accessed by unauthenticated users.
However, it never hurts to add an extra layer of validation, as Next.js deduplicates any similar duplicate requests. After confirming the session, it retrieves the user's ID from the database; if the user is not found, it redirects to the registration page.
Finally, it renders the AddTask and Board components, passing the user's ID as a prop.
There is one last thing remaining: if you’ve noticed, in the
Inside the src/app/kanban/[taskId] directory, create a new file page.tsx with the following lines of code:
cd kanban-ai-realtime-localization
The same is true here: we first validate the session. As mentioned earlier, this should never be executed because of the middleware we already have in place.
Then, we simply fetch the task from the database using the taskId we received as a prop. If the task does not exist, we redirect the user to the /kanban page. If it does exist, we display the title and description of the task.
Finally, let’s work on the root Home page of our application (/ route). Modify the src/app/page.tsx with the following lines of code:
npm install @ai-sdk/openai @tolgee/react @tolgee/web @tolgee/format-icu @tanstack/react-query @prisma/client ai socket.io socket.io-client prisma next-auth date-fns nodemon ts-node zod tsconfig-paths react-beautiful-dnd
Here, we simply check if the user is authenticated. If they are, they are sent to the /kanban route; if not, they are redirected to the login page.
That is literally all we need to do to get our Kanban board running perfectly. Now, you should have a fully functioning Kanban board with authentication, localization, and real-time support. ?
Wow! ?? We’ve accomplished a lot together today.
If you made it this far, you’ve successfully built an AI and localization-powered Kanban board from scratch along with the help of a blog post. Give yourself a well-deserved pat on the back!
Star the Tolgee repository ⭐
Follow Tolgee for more content like this.
Share your thoughts in the comment section below! ?
Thank you so much for reading! ? ?
The above is the detailed content of Building a Kanban Board with Next.js,Vercel AI and Tolgee. For more information, please follow other related articles on the PHP Chinese website!