Next.js Discord

Discord Forum

Can File be both server and client?

Answered
Bighead carp posted this in #help-forum
Open in Discord
Bighead carpOP
async function getSession() {
    if (isServer()) {
        const { getServerSession } = await import("./serverSession");
        const serverSession = getServerSession();
        return serverSession;
    }

    const { data: res } = await AppHttpClient.get<SessionResponse>("/api/auth/session");
    return res;
}


For example I want to have server do initial page fetch for example getThing() -> Fetch session accessToken from server cookies
If not server then make request to route /api/auth/session to get current session information so I can use useQuery
Answered by Bighead carp
Ok so doing:

"use server";
import { SessionResponse } from "@/core/models/project/SessionResponse";
import { cookies } from "next/headers";
import jwt from "jsonwebtoken";
import { Session } from "@/core/models/project/Session";

export async function getServerSession(): Promise<SessionResponse> {
    try {
        const sessionCookie = cookies().get("session");

        if (!sessionCookie || !sessionCookie.value) {
            return {
                code: "SESSION_NOT_FOUND",
                authenticated: false
            };
        }

        const decoded: Session = jwt.verify(sessionCookie.value, process.env.SESSION_SECRET!) as Session;

        return {
            code: "OK",
            authenticated: true,
            user: decoded.user,
            accessToken: decoded.accessToken
        };
    } catch (ex) {
        console.error(ex);

        return {
            code: "SESSION_NOT_FOUND",
            authenticated: false
        };
    }
}


and doing in next config seems to resolve my issue
/** @type {import('next').NextConfig} */
const nextConfig = {
    experimental: {
        serverActions: true,
      },
};

module.exports = nextConfig;
View full answer

45 Replies

Bighead carpOP
Though I get One of these is marked as a client entry with "use client":

When I import it in client component
Hello
I can help
A file can a server and a client in Node.Js
using the built-in http module to create and listen to an HTTP server.
a example is this
// Import the http module
var http = require('http');

// Create a web server
var server = http.createServer(function (req, res) {
  // Write a response header
  res.writeHead(200, {'Content-Type': 'text/plain'});
  // Write a response body
  res.end('Hello World\n');
});

// Listen to the server on port 3000
server.listen(3000, function () {
  console.log('Server listening on port 3000');
});

// Create a client request
var client = http.get('http://example.com', function (res) {
  // Log the status code
  console.log('Status: ' + res.statusCode);
  // Log the response headers
  console.log('Headers: ' + JSON.stringify(res.headers));
  // Log the response data
  res.on('data', function (chunk) {
    console.log('Data: ' + chunk);
  });
});

// Handle any errors
client.on('error', function (err) {
  console.error('Error: ' + err.message);
});
Bighead carpOP
@Bashamega so a proxy?
@Bighead carp <@1051827169195737118> so a proxy?
Yes, a proxy server
Bighead carpOP
My backend in c#
So I need proxy to

/api -> c#
other route -> Next13
@Bighead carp My backend in c#
C# is a popular and powerful programming language that can be used to create web applications, desktop applications, mobile applications, games, and more. However, C# is not natively supported by Next.js, which is a React framework that runs on Node.js. Therefore, you will need to find a way to connect your C# backend with your Next.js frontend.

One possible way to do this is to use a RESTful API approach. This means that you will create a separate web service using C# that exposes some endpoints for your Next.js frontend to consume. For example, you can use ASP.NET Core or NancyFX to create a web API project in C# that handles the business logic and data access for your application. Then, you can use the fetch or axios libraries in Next.js to make HTTP requests to your C# API endpoints and get the data you need. This way, you can leverage the benefits of both C# and Next.js in your project.

Another possible way to do this is to use a serverless approach. This means that you will deploy your C# functions as Azure Functions or AWS Lambda functions and use them as your backend. For example, you can use the Azure Functions extension for Visual Studio Code or the AWS Toolkit for Visual Studio to create and deploy C# functions in the cloud. Then, you can use the next-connect or next-iron-session libraries in Next.js to invoke your C# functions and get the data you need. This way, you can avoid managing servers and scaling issues for your backend.

These are some of the ways to use C# backend with Next.js frontend, but there may be other ways depending on your specific needs and preferences. You can find more information and examples about using C# backend with Next.js frontend in these web search results. I hope this helps you with your project. 😊
Bighead carpOP
chat-gpt says hello
@Bighead carp chat-gpt says hello
sorry. I am not good in c#
@Bashamega using the built-in http module to create and listen to an HTTP server.
this server doesn't make any sense. please reread and see if it fits nextjs and/or the question at all, because it doesn't.
@joulev try checking for the type of `window`
Bighead carpOP
Thank you for replying
I do check code is:
export function isServer() {
    return typeof window === "undefined";
}
I need to see how these "use client" and "server-only" if any play together
Bighead carpOP
One sec
Btw why does middelware not support crypto library is there any way to force nodejs runtime over edge? From documentation it only seems edge is supported
You would need workarounds for that
But I would just use edge-compatible libraries
The edge does have some crypto APIs supported, check the documentation for details
Bighead carpOP
Is there way to run multiple middelwares? I think I just use web safe JWT library in middelware action, and use JWT node library in other parts
Bighead carpOP
I get error here:
"use client";

import { useAuthStore } from "@/store/useAuthStore";
import { useRouter } from "next/navigation";
import { useEffect } from "react";

export function RequireAuth({ children }: { children: React.ReactNode }) {
    const router = useRouter();
    const { getSession } = useAuthStore();
    const token = useAuthStore(state => state.accessToken);

    useEffect(() => {
        const performSessionCheck = async () => {
            const session = await getSession();

            if (!session.authenticated) {
                return router.push("/auth/signin");
            }
        };

        performSessionCheck();
    }, [router, token]);

    return <>{children}</>;
}


error is import { cookies } from "next/headers"; You're importing a component that needs next/headers. That only works in a Server Component but one of its parents is marked with "use client", so it's a Client Component.
But not sure why it's importing since it should not import for client
useAuthStore implements following:

using zustand + immer

const current = get();
const userSession = await session.getSession();

set((state) => {
    state.isLoggedIn = userSession.authenticated;
    state.lastCached = dayjs();
    
    if (userSession.authenticated) {
        state.user = userSession.user;
        state.accessToken = userSession.accessToken;
    }
});
and getSession is just
async function getSession() {
    if (isServer()) {
        const { getServerSession } = await import("./serverSession");
        const serverSession = getServerSession();
        return serverSession;
    }
    
    const { data: res } = await AppHttpClient.get<SessionResponse>("/api/auth/session");
    return res;
}
getServerSession code is
import { SessionResponse } from "@/core/models/project/SessionResponse";
import { cookies } from "next/headers";
import jwt from "jsonwebtoken";
import { Session } from "@/core/models/project/Session";

export function getServerSession(): SessionResponse {
    try {
        const sessionCookie = cookies().get("session");

        if (!sessionCookie || !sessionCookie.value) {
            return {
                code: "SESSION_NOT_FOUND",
                authenticated: false
            };
        }

        const decoded: Session = jwt.verify(sessionCookie.value, process.env.SESSION_SECRET!) as Session;

        return {
            code: "OK",
            authenticated: true,
            user: decoded.user,
            accessToken: decoded.accessToken
        };
    } catch (ex) {
        console.error(ex);

        return {
            code: "SESSION_NOT_FOUND",
            authenticated: false
        };
    }
And here I get error
in next/headers
Bighead carpOP
Ok so doing:

"use server";
import { SessionResponse } from "@/core/models/project/SessionResponse";
import { cookies } from "next/headers";
import jwt from "jsonwebtoken";
import { Session } from "@/core/models/project/Session";

export async function getServerSession(): Promise<SessionResponse> {
    try {
        const sessionCookie = cookies().get("session");

        if (!sessionCookie || !sessionCookie.value) {
            return {
                code: "SESSION_NOT_FOUND",
                authenticated: false
            };
        }

        const decoded: Session = jwt.verify(sessionCookie.value, process.env.SESSION_SECRET!) as Session;

        return {
            code: "OK",
            authenticated: true,
            user: decoded.user,
            accessToken: decoded.accessToken
        };
    } catch (ex) {
        console.error(ex);

        return {
            code: "SESSION_NOT_FOUND",
            authenticated: false
        };
    }
}


and doing in next config seems to resolve my issue
/** @type {import('next').NextConfig} */
const nextConfig = {
    experimental: {
        serverActions: true,
      },
};

module.exports = nextConfig;
Answer
Bighead carpOP
Though I'm not sure if there is a way to do it without this experimental version
Bighead carpOP
Bunp
Bighead carpOP
Still looking
Well rotation of access token, and refresh token does not work - [JWT Token refresh - getting outdated token to JWT callback](https://github.com/nextauthjs/next-auth/discussions/6642) and [Tokens rotation does not persist the new token](https://github.com/nextauthjs/next-auth/issues/7558)
in next13 app router so I ditched that library
Besides that if you're referring to proxy approach it is something I'm looking into, but I need some solution right know that will solve the issue.
If none of those options apply, could you please share the solution to which you are referring to?