Course Content
Next.js 14
Next.js 14
Creating Item
Create an Invoice - Step by Step
- Make a Form: First, we need a form to get the details. This is where the user puts in the information for the new invoice;
- Use a Server Action: Make a special action on the server to handle the form data. When someone fills out the form, this action gets triggered;
- Get Data from the Form: Inside the Server Action, take out the information from the form. Think of it like unpacking a box - you want to see what's inside;
- Check and Prepare the Data: Look at the data and make sure it's all good. It's like checking that the ingredients for a recipe are fresh and correct. Once everything's okay, get it ready to put into the database;
- Insert Data: Put the data into the database;
- Refresh Cache and Go Back to Invoices Page: After adding the data, update the cache. It's like making sure everyone gets the latest information. Then, send the user back to the invoices page so they can see the new invoice they just created.
Back to the Project
1. Make a Form
Make a new folder named ' create ' within the app/dashboard/invoices
directory. Create a new file called page.tsx
inside this folder. This file will serve as a new page allowing users to generate an invoice.
Copy and paste the following code into the page.tsx
file:
The page uses a Server Component to gather user information and then sends it to a ready-made <Form>
component. Here's a breakdown of the <Form>
component:
- Dropdown for users;
- Input field for the amount;
- Radio buttons for the status;
- Submit button to complete.
If you click on the "Create Invoice" button, you should be directed to a form that will prompt you to fill out the necessary information.
2. Use a Server Action
- Navigate to the
lib
directory; - Create a new file named
actions.ts
; - Add the
'use server'
directive at the top;- Why
'use server'
? - It allows the functions to be versatile and usable in both Client and Server components. It's a handy way to organize Server Actions, but we can also embed them directly in Server Components if needed.
- Why
- Creating a Server Action function.
Next, within the <Form>
component, import createInvoice
from the actions.ts
file. Include an action
attribute in the <form>
element and invoke the createInvoice
action.
3. Get Data from the Form
Return to app/lib/actions.ts
to extract the values of formData
using the .get(name)
method. Once you've completed this task, you can fill out the form and review the inputted data in the terminal console.
Result:
4. Check and Prepare the Data
Before storing the form data in the database, it's crucial to check if it's in the right format and has the correct types. In our course, we've been using a specific format for the invoice table data.
To make this process easier, we have a couple of options for type validation. Instead of manually checking types, we can use Zod, a TypeScript-first validation library. It's a handy tool that simplifies the validation task.
Here's what we need to do in the actions.ts
file:
- Import Zod into the
actions.ts
file; - Create a schema using Zod that matches the structure of the form object. This schema acts as a set of rules to ensure the
formData
is correct before it goes into the database.
Then, we pass the rawFormData
to CreateInvoice
to validate the types.
Let's convert the amount to cents and create a new date with the format "YYYY-MM-DD" using vanilla JS.
5. Insert Data
Now that we have all the necessary values, we can use sql
to send them to the database.
6. Refresh Cache and Go Back to Invoices
Next.js has a handy feature called the Client-side Router Cache. It keeps track of where users have been on the site for a certain period. This cache, combined with prefetching, ensures that users can switch between different pages quickly without bombarding the server with too many requests.
Now, here's what we want to do:
- Since we've updated the data on the invoices page, we want to ensure users see the latest information. To do this, we clear the cache using
revalidatePath
function. This ensures a fresh request is sent to the server, pulling in the most recent data; - After updating the data and clearing the cache, we want to guide the user back to the invoices page smoothly. We achieve this by using
redirect
function. It's like giving them directions back to where they were.
In Practice
Thanks for your feedback!