Module not found Error when trying to use Server Actions
Unanswered
gin posted this in #help-forum
ginOP
Module not found: Can't resolve 'react-server-dom-webpack/client'
177 Replies
ginOP
import { createSession } from "@/utils/user";
<form action={createSession}>
<span data-uia="profile-button">
<button type='submit' className="profile-button preferred-action">Login</button>
</span>
</form>"use server";
export async function createSession() {
console.log('createSession() called');
};This should be the correct way to use Server Actions right?
Import trace for requested module:
./src/utils/user.tsx
./pages/index.tsx
â—‹ Compiling /_error ...
⨯ ./node_modules/next/dist/build/webpack/loaders/next-flight-loader/action-client-wrapper.js:19:63
Module not found: Can't resolve 'react-server-dom-webpack/client'
https://nextjs.org/docs/messages/module-not-found
Import trace for requested module:
./src/utils/user.tsx
./pages/index.tsxDo you have it enabled in your next.config.js?
@Marchy Do you have it enabled in your next.config.js?
ginOP
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
serverActions: true,
},
}
module.exports = nextConfigâ–² Next.js 13.5.3
- Local: http://localhost:3000
- Environments: .env.local
- Experiments (use at your own risk):
· serverActions
✓ Ready in 3.7sMaybe its how i render html?
Possibly, I don't see anything that jumps out at me with what you've shared so far
I would try to replicate it with a new page
in my root i have/pages/index.tsx
import Home from "@/app/Home/home";
import RootLayout from "@/app/layout";
export default function Indexpage() {
return (
<RootLayout>
<Home />
</RootLayout>
);
}And this is my RootLayout function
import '@/styles/main.scss';
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<>
<div className="rootLayout">
<div className='appMountPoint'>{children}</div>
</div>
</>
)
}Oh, server actions are only in the app directory
@Marchy Oh, server actions are only in the app directory
ginOP
The Home function is in the app directory
@Marchy 👆
ginOP
Wait thats the issue?
Why do you have a file in the pages directory?
@Marchy Why do you have a file in the pages directory?
ginOP
Because i wanted to make use of the routing feature in pages
Ah, yeah. Can't use both. It's either app or pages, both have file based routing
in app dir it's just
/route/to/page.jsginOP
Lemme try, if that solves issue i love you
@Marchy in app dir it's just `/route/to/page.js`
ginOP
"getServerSideProps" doesnt work in /app?
@gin "getServerSideProps" doesnt work in /app?
nope, with server components you can just fetch data or access a database as needed
https://nextjs.org/docs/app/building-your-application/upgrading/app-router-migration#server-side-rendering-getserversideprops
https://nextjs.org/docs/app/building-your-application/upgrading/app-router-migration#server-side-rendering-getserversideprops
@Marchy nope, with server components you can just fetch data or access a database as needed
https://nextjs.org/docs/app/building-your-application/upgrading/app-router-migration#server-side-rendering-getserversideprops
ginOP
That means i have to create a API endpoint to do something same in /app?
@gin That means i have to create a API endpoint to do something same in /app?
You don't need an API endpoint with server components usually. But if you do need one, those have been replaced with route handlers in the app dir
https://nextjs.org/docs/app/building-your-application/upgrading/app-router-migration#api-routes
https://nextjs.org/docs/app/building-your-application/upgrading/app-router-migration#api-routes
@Marchy You don't need an API endpoint with server components usually. But if you do need one, those have been replaced with route handlers in the app dir
https://nextjs.org/docs/app/building-your-application/upgrading/app-router-migration#api-routes
ginOP
Wait i tought /app components are automatically client components and a rendered by the client?
Because i have to get some data from the client before i load the page
That worked well in /pages
Thats why i switched from create-react-app to next in the first place
@gin Wait i tought /app components are automatically client components and a rendered by the client?
They're pre-rendered to client components or serverless functions (SSR) automatically depending on what it needs. So if you access the database on the page level, that will run SSR. If you're fetching to an external API and it's cached, it may build static but regenerate on interval that you can configure
The compiler takes care of all that for you, but the conventions are different from the pages dir
@Marchy They're pre-rendered to client components or serverless functions (SSR) automatically depending on what it needs. So if you access the database on the page level, that will run SSR. If you're fetching to an external API and it's cached, it may build static but regenerate on interval that you can configure
ginOP
Can you give me a example how can i make use of SSR to pre-render html based on the request data?
for /app
Where are you requesting the data from? A database? an api endpoint?
@Marchy https://nextjs.org/docs/app/building-your-application/data-fetching
ginOP
Where exactly?
I only see that i have to create a route and use fetch
I only see that i have to create a route and use fetch
Well
Its a clientside database stored in a cookie
And the encryption is only possible on the server
@gin Its a clientside database stored in a cookie
Do you mean that you're using cookies for data storage?
@Marchy Do you mean that you're using cookies for data storage?
ginOP
Yes, iron-session i think it was called
ginOP
Whats the Problem?
Oh just the session data?
@Marchy Oh just the session data?
ginOP
Just session data
I thought you meant like user data too for a second (cookies were actually used for general data storage years ago lool)
Are you trying to configure iron session with next specifically?
@Marchy I thought you meant like user data too for a second (cookies were actually used for general data storage years ago lool)
ginOP
User data?
I mean im storing the data for the user on his pc.
I mean im storing the data for the user on his pc.
So i can say that the data is only stored on the users pc
Nothing saved on the server
So in that case, "data fetching" would all happen client side
are you using indexdb or local storage or something?
@Marchy are you using indexdb or local storage or something?
ginOP
Im not, the "data fetching" is only for getting the users prefered color or a saved avatar. That would be saved in the cookie. That cookie is encrypted by iron-session
And it can be only decrypted by the server
You can get the cookies here
ginOP
No, thats not the problem
@gin And it can be only decrypted by the server
by "on the server" do you mean you have a seperate backend?
@Marchy by "on the server" do you mean you have a seperate backend?
ginOP
I dont, that fetching happened before the html render in /pages
just like php
getServerSideProps
Then it return the html based of the props returned
I'm not sure if I'm understanding what you're asking. You're talking about storing data locally, but also needing to use getServerSideProps.
You will understand it
ginOP
So.
Im actually pretty good in making websites. Made plenty good websites using react and express for the Api.
This time i wanted to start with nextjs and i created a new project.
in /pages i have
index.tsx and browse.tsx
When the user goes on .org/browse the getServerSideProps checks for the session cookie. If its not present it prompts the user to go back to index.tsx
Get it? So i pass the returned prop to the function and then render based of the boolean.
Im actually pretty good in making websites. Made plenty good websites using react and express for the Api.
This time i wanted to start with nextjs and i created a new project.
in /pages i have
index.tsx and browse.tsx
When the user goes on .org/browse the getServerSideProps checks for the session cookie. If its not present it prompts the user to go back to index.tsx
export default function Browse({ rs }: { rs: SUProp }) {
return (
<RootLayout>
<>
{rs && rs.showLogin ? <Login rs={rs} /> : <h1>Please go back to <a href="../">Home</a> to login</h1>}
</>
</RootLayout>
);
};
export const getServerSideProps = withIronSessionSsr(async (context) => {
const rs: SUProp | undefined = context.req.session.user;
if (!rs) {
return {
props: {
rs: {
showLogin: false
}
}
};
}
return {
props: {
rs
}
}
}, sessionOptions);Get it? So i pass the returned prop to the function and then render based of the boolean.
The rest you can explain for yourself right?
Im listening to music and cant write a whole essay rn
Its a simple website with simple code.
it is nothing more and nothing less.
For me this isnt complicated and its fun @Marchy.
it is nothing more and nothing less.
For me this isnt complicated and its fun @Marchy.
I could directly create the session on request yes, but i wanted to make it possible for the user to control his experience on the website
So, create a session with server actions
that was my goal
And i was sure i do this this in 2mins
Ah, you're looking for middleware
https://nextjs.org/docs/app/building-your-application/routing/middleware
https://nextjs.org/docs/app/building-your-application/routing/middleware
You can handle the redirects for auth there by setting the matching paths
You can just configure it once now instead of needing to do it in getServerSideProps
There are some examples here with iron session specifically
https://github.com/vvo/iron-session/issues/560
But really, iron session is just wrapping cookie headers
https://github.com/vvo/iron-session/issues/560
But really, iron session is just wrapping cookie headers
@Marchy Ah, you're looking for middleware
https://nextjs.org/docs/app/building-your-application/routing/middleware
ginOP
Middleware sounds cool, but how can i use the data i return?
I really want to reduce the usage of a booring api route.
@gin Middleware sounds cool, but how can i use the data i return?
You don't, middleware should be very slim because it runs before every request (for things like auth where you don't want to send ANY data to an unauthenticated user). Data you can just fetch from within the server component on the component level
like if you need to access cookies you can just
import { cookies } from 'next/headers'
export default function Page() {
const cookieStore = cookies()
const theme = cookieStore.get('theme')
return '...'
}middleware would be like using app.use(..)
@Marchy You don't, middleware should be very slim because it runs before every request (for things like auth where you don't want to send ANY data to an unauthenticated user). Data you can just fetch from within the server component on the component level
ginOP
My website is just 2-3 pages so yeah. Yk what? I will stay with /pages.
I will create 1-2 endpoints. One for creating a session and one for setting session data
I will create 1-2 endpoints. One for creating a session and one for setting session data
@gin My website is just 2-3 pages so yeah. Yk what? I will stay with /pages.
I will create 1-2 endpoints. One for creating a session and one for setting session data
That's perfectly acceptible, pages is still supported. Just won't get the react 18 features
I've been recommending app dir for more like application development where there's lots of moving parts
@Marchy That's perfectly acceptible, pages is still supported. Just won't get the react 18 features
ginOP
Wait so you telling me i cant just render some in /pages and some in /app?
If i want to make use of a new feature i could just render the route in /app
right
@gin Wait so you telling me i cant just render some in /pages and some in /app?
You can but it gets weird with the server-side stuff. They're technically deployed seperately
ginOP
Would be double work
so it'd be like maintining two seperate apps in the same repo
app dir is better tbh, but it's very different from pages not just in code but in architecture so something to consider
ginOP
I want to use app
Only thing with the middlware i want to use the data returned as prop
Pass it directly to the component
I cant render the component in the middlware right?

@gin Only thing with the middlware i want to use the data returned as prop
This happens in your component, not in middleware. You just import the data fetching function directly
@Marchy This happens in your component, not in middleware. You just import the data fetching function directly
ginOP
yeah you told me that the middleware fetches data and then the page is rendered in the component
Cant i pass props from the middleware?
async function getData(){
await new Promise(resolve => setTimeout(resolve, 1000));
return {message: 'done'}
}
export default async function Home(){
const {message} = await getData();
return(
<div>
{message}
</div>
)
}like this
@gin Cant i pass props from the middleware?
what would you be passing?
You can't do any data fetching within middleware
But you can read/set cookies
ginOP
Oh i cant?
I tought it is like the middleware in express
Nope, that means you'd have a hard request to your data source on every page load which is bad for performance
instead you can break it up with server components and stream them as they load
so you could have just a "nav" component that fetches (and caches!) the user data
ginOP
and what if i want to make use of the data outside of that component?
or like a data table that saves to a database
@gin and what if i want to make use of the data outside of that component?
pass it as props, pass it as context, or just fetch it again where you need it in a different component. Next automatically de-dupes requests.
props and context are the react-level way to pass things around, but generally you can avoid it by just using server code directly. It's much more like old PHP
Thats what im trying to do in this project
Like php
https://nextjs.org/docs/app/api-reference/functions/server-actions
This is where a lot of the magic happens in app dir
This is where a lot of the magic happens in app dir
ginOP
Put on cloudflare and boom nobody abusing your api
@gin Put on cloudflare and boom nobody abusing your api
Can't abuse an api if you don't have one 

Hold on can i just fetch data using server actions on page load?
@gin Hold on can i just fetch data using server actions on page load?
Well, it doesn't exactly happen on page load but yes
It might be pre-cached by the serverless function and rendered as static depending on how you're fetching it
ginOP
nvm
but it executes only on page load
@gin Load it once
nope, requests are deduped
Next will try to pre-render everything it can to re-use all of your components as static HTML. Everything else it fills in on request
this talks about pages dir, but same principal just different framework with app dir
ginOP
But server actions would be like passing a paremeter to the page
?blablabla=123
Thats also not nice
@gin But server actions would be like passing a paremeter to the page
nope, no more passing props. Params still get passed into the folder name as
[param] but you just await the result of the server code directlyasync function getData(param){
await new Promise(resolve => setTimeout(resolve, 1000));
return {message: 'done'}
}
export default async function Home({params}){
const {message} = await getData(params.id);
return(
<div>
{message}
</div>
)
}ginOP
So if i use server actions and render the page in app it will act like getServerSideProps in /pages?
And in that server action i can get the context?
Request Object for example
Or Cookies
kind of
that's where things get a little weird. There really is no such thing as a "request object" anymore because everything is pieced out
that's where things get a little weird. There really is no such thing as a "request object" anymore because everything is pieced out
generally, you won't actually need the whole request object
and if you do that's kinda code smell
ginOP
lol
So
Cookies (auth stuff) you can still access directly
but generally you're only fetching exactly what you need to render the component
also authentication cookies get applied automatically when using
fetch for posting dataginOP
My brain is exploding rn even tho it easy. Like actually
I understand everything and i want to discuss but
Im awake too long
@gin My brain is exploding rn even tho it easy. Like actually
lool, 99% of the issues I've seen people run into next is because they're trying to do too much instead of just letting the framework handle it 😂
@gin Im awake too long
Get some sleep, i'll be around ðŸ‘
Fixed it with:
Having the /app only handling the Indexpage
So i can use server actions
Rest is done in /pages
ðŸ‘


