diff --git a/bun.lockb b/bun.lockb
index ac4c8a5..0b270e3 100755
Binary files a/bun.lockb and b/bun.lockb differ
diff --git a/content/blogs/server-actions.mdx b/content/blogs/server-actions.mdx
index a486b90..db8318b 100644
--- a/content/blogs/server-actions.mdx
+++ b/content/blogs/server-actions.mdx
@@ -1,6 +1,6 @@
---
-title: 'A Deep Dive To Next.js 14 Server Actions'
-summary: 'Harness the power of Next.js 14 Server Actions for streamlined data fetching and mutations in your Nextjs applications.'
+title: 'A Deep Dive To Server Actions In NextJs'
+summary: 'Harness the power of Server Actions for streamlined data fetching and mutations in your Nextjs applications.'
slug: 'server-actions'
publishedAt: 'April 13, 2024'
tags:
@@ -13,13 +13,14 @@ tags:
Server-Components,
JavaScript,
TypeScript,
+ React-19,
]
published: true
---
## Introduction
-If you've ever built web applications that involve **forms** , **real-time updates** , or **complex data interactions**, you know the struggle can be real. Traditionally, these features often required setting up separate `API` endpoints and managing intricate client-side state. Next.js 14 Server Actions come to the rescue! They provide a smooth solution, allowing you to execute server-side logic directly from your React components, just like calling a regular function.
+If you've ever built web applications that involve **forms** , **real-time updates** , or **complex data interactions**, you know the struggle can be real. Traditionally, these features often required setting up separate `API` endpoints and managing intricate client-side state. [Server Actions](https://react.dev/reference/rsc/server-actions) come to the rescue! They provide a smooth solution, allowing you to execute server-side logic directly from your React components, just like calling a regular function.
## What are Server Actions?
@@ -146,11 +147,12 @@ export default privateClient;
**Github**
-Follow this [github guide](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/creating-an-oauth-app) for creating Oauth
+Follow this [github guide](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/creating-an-oauth-app) for creating Oauth.
-```env
-CALLBACK_ENV https://example.com/api/auth/callback/github
-```
+
+ Make sure to add `http://localhost:3000/api/auth/callback/github` as callback
+ url in github Oauth application.
+
After creating Oauth in github copy `API` keys from github as it required by AuthJs.
@@ -166,7 +168,7 @@ Visit the [Vercel App](https://generate-secret.vercel.app/32) to generate secret
Add all the key to you .env.local.
-```.env
+```
# .env.local
AUTH_SECRET=
@@ -179,9 +181,10 @@ AUTH_GITHUB_SECRET=
[Google OAuth documentation](https://developers.google.com/identity/protocols/oauth2)
-```env
-CALLBACK ENV = https://example.com/api/auth/callback/google
-```
+
+ Make sure to add `http://localhost:3000/api/auth/callback/google` as callback
+ url in Oauth application.
+
```.env
# .env.local
@@ -212,7 +215,6 @@ export const config = {
} satisfies NextAuthConfig;
export const { handlers, auth } = NextAuth(config);
-
```
Here we are using supabase adapter and our choice of providers for auth. You can add more providers from [AuthJs Providers](https://authjs.dev/getting-started#official-providers).
@@ -278,7 +280,6 @@ export function SignOut(props: React.ComponentPropsWithRef) {
);
}
-
```
### 5.Create Navbar
@@ -352,20 +353,15 @@ You can check that now our authentication system is working, we are able to logi
In development if your Oauth is not redirect back to application add
- `AUTH_REDIRECT_PROXY_URL` in env.
+ `AUTH_REDIRECT_PROXY_URL` in .env.local. Only add this in development.
- If you find any difficulty or have some error you can react out to
- [me](/contact) or check my source code.
+ If you find any difficulty or have some error you can contact to
+ [me](/contact) or check my source code on
+ [Github](https://github.com/patelvivekdev/server-actions).
-```
-# .env.local
-
-AUTH_REDIRECT_PROXY_URL = /api/auth #only add in dev
-```
-
You can check that our user are now stored in supabase as well.
## Building a Todo App with Server Actions
@@ -476,11 +472,12 @@ export function SubmitButton({
);
}
-
```
-
- This hook might change in new version of react.
+
+ If you are using `useFormStatus` make sure to use it as a child component of
+ parents form. In out case we are using it in `AddForm.tsx`. In react19 you can
+ also use `useActionState` for pending state.
### 3.Create actions.ts
@@ -544,11 +541,12 @@ We will add this action to our form with the help of `useFormState`. It is new h
> As per react `useFormState` is a Hook that allows you to update state based on the result of a form action.
- As of now React is changing this hook. If you are interested check this github
- [discussion](https://github.com/facebook/react/pull/28491)
+ As of now React19 is changing this hook. If you are interested check this
+ github [discussion](https://github.com/facebook/react/pull/28491). If you are
+ using React19 you can use `useActionState` instead of `useFormState`.
-This means that we will get error message or success message along with boolean to from server action.
+This means that we will get state with out server action such as error message or success message from server action.
We will show that message with [react-hot-toast](https://react-hot-toast.com/docs).
@@ -657,7 +655,6 @@ export default function AddTodo({ user }: { user: User }) {
);
}
-
```
### 5.Add validation
@@ -725,7 +722,6 @@ export async function addTodo(email: string, prevState: any, formData: FormData)
};
}
}
-
```
After creating schema we will use `safeParse`.
@@ -742,11 +738,17 @@ By default next caches every routes, so when we add the todo we want to show to
That means we have to delete the old cache and update the ui.
-This is what revalidatePath does for us. Learn more about caching in [NextJS](https://nextjs.org/docs/app/building-your-application/caching)
+This is what revalidatePath does for us.
+
+
+ In current version of NextJs 14, next js caches everything by default, but in
+ future version it will be changed. Learn more about caching in
+ [NextJS](https://nextjs.org/docs/app/building-your-application/caching).
+
### 7.TodoList
-now we will show the list pf todos with some actions button.
+now we will show the list of todos with some actions button.
**db.ts**
@@ -908,7 +910,6 @@ export default function EditForm({ todo }: { todo: any }) {
**DeleteForm**
```
-
// DeleteForm.tsx
'use client';
@@ -1077,7 +1078,6 @@ export default async function PrivatePage() {
```
// profile/ChangeAvatarForm.tsx
-
import { auth } from '@/app/auth';
import { SignIn, SignOut } from '@/components/auth-components';
import Image from 'next/image';
@@ -1105,7 +1105,6 @@ export default async function PrivatePage() {
);
}
-
```
This is same as AddForm, we will change the input type to `file`.
@@ -1113,6 +1112,8 @@ This is same as AddForm, we will change the input type to `file`.
### 3.Create action
```
+// actions.ts
+
// =============================== Change Avatar ===============================
export async function changeAvatar(email: string, prevState: any, formData: FormData) {
const avatar = formData.get('avatar') as File;
@@ -1200,13 +1201,13 @@ Because we have image in two places we have to revalidate two path.
## Conclusion
-Next.js 14 Server Actions offer a powerful and elegant way to manage data interactions in your React applications. By mastering this concept, you'll create more dynamic and performant web experiences for your users.
+React 19 Server Actions offer a powerful and elegant way to manage data interactions in your React applications. By mastering this concept, you'll create more dynamic and performant web experiences for your users.
## Links
- [Github Repo](https://github.com/patelvivekdev/server-actions/)
- [Live Demo](https://server-actions-patelvivekdev.vercel.app/)
-- [Next.js 14 Server Actions](https://nextjs.org/docs/app/api-reference/functions/server-actions)
+- [Server Actions](https://nextjs.org/docs/app/api-reference/functions/server-actions)
- [React server actions](https://react.dev/reference/react/use-server#usage)
- [React Form](https://react.dev/reference/react-dom/components/form#handle-form-submission-with-a-server-action)
- [Supabase](https://supabase.com/)
diff --git a/package.json b/package.json
index 61ec867..d253b47 100644
--- a/package.json
+++ b/package.json
@@ -15,8 +15,8 @@
},
"dependencies": {
"@fec/remark-a11y-emoji": "^4.0.2",
- "@next/bundle-analyzer": "15.0.0-canary.12",
- "@next/eslint-plugin-next": "15.0.0-canary.12",
+ "@next/bundle-analyzer": "15.0.0-canary.16",
+ "@next/eslint-plugin-next": "15.0.0-canary.16",
"@radix-ui/react-alert-dialog": "^1.0.5",
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-label": "^2.0.2",
@@ -30,9 +30,10 @@
"cmdk": "^1.0.0",
"gray-matter": "^4.0.3",
"lucide-react": "^0.373.0",
- "next": "15.0.0-canary.12",
+ "next": "15.0.0-canary.16",
"next-mdx-remote": "^4.4.1",
"next-themes": "^0.3.0",
+ "patelvivek.dev": ".",
"react": "19.0.0-rc-f994737d14-20240522",
"react-dom": "19.0.0-rc-f994737d14-20240522",
"react-hot-toast": "^2.4.1",
@@ -46,21 +47,21 @@
},
"devDependencies": {
"@tailwindcss/typography": "^0.5.13",
- "@types/node": "^20.14.1",
+ "@types/node": "^20.14.2",
"@types/react": "18.3.2",
"@types/react-dom": "18.3.0",
"@types/rss": "^0.0.32",
"autoprefixer": "^10.4.19",
"eslint": "^8.57.0",
- "eslint-config-next": "^15.0.0-rc.0",
+ "eslint-config-next": "15.0.0-canary.16",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3",
"husky": "^9.0.11",
"lint-staged": "^15.2.5",
"postcss": "^8.4.38",
- "prettier": "^3.3.0",
+ "prettier": "^3.3.1",
"prettier-plugin-tailwindcss": "^0.5.14",
- "tailwindcss": "^3.4.3",
+ "tailwindcss": "^3.4.4",
"typescript": "^5.4.5"
}
}