hey all. I'm running NextJS 14 and I've
# spicedb
p
hey all. I'm running NextJS 14 and I've installed and wanting to use
@authzed/authzed-node
via server actions. I keep on getting the following:
Copy code
Module not found: Can't resolve 'fs'
Module not found: Can't resolve 'net'
Module not found: Can't resolve 'tls'
Module not found: Can't resolve 'http2'
I would have thought these already be covered by the node instance from next? Thanks
Copy code
Module not found: Can't resolve 'tls'

 https://nextjs.org/docs/messages/module-not-found

 Import trace for requested module:
 ../../node_modules/.pnpm/@grpc+grpc-js@1.10.1/node_modules/@grpc/grpc-js/build/src/index.js
 ../../node_modules/.pnpm/@authzed+authzed-node@0.13.0/node_modules/@authzed/authzed-node/dist/src/authzedapi/authzed/api/v1/experimental_service.grpc-client.js
 ../../node_modules/.pnpm/@authzed+authzed-node@0.13.0/node_modules/@authzed/authzed-node/dist/src/v1.js
 ../../node_modules/.pnpm/@authzed+authzed-node@0.13.0/node_modules/@authzed/authzed-node/dist/src/index.js
 ./src/app/mutations/authzed/createSchema.ts
 ./src/app/authzed/page.tsx
  ⨯ ../../node_modules/.pnpm/@grpc+grpc-js@1.10.1/node_modules/@grpc/grpc-js/build/src/channel-credentials.js:20:0
 Module not found: Can't resolve 'tls'

 https://nextjs.org/docs/messages/module-not-found
v
@Joey @Sam ☝️
s
We haven't tested with nextjs 14 yet but a few things that come to mind to check are verifying the runtime for that route is nodejs (this is the default so only applies if you explicitly set it to edge or serverless) and that authzed-node is only imported in files that have server components only. You may have to rearrange components to separate server and client components or you could try this https://stackoverflow.com/a/76513531
p
> You may have to rearrange components to separate server and client components or you could try this I'm using the authzen library in the server action only. So it's only running from the server. I have already split up the client UI and then server actions into two distinct camps. > verifying the runtime for that route is nodejs From the nextjs package.json from vercel
Copy code
"engines": {
    "node": ">=18.17.0",
    "pnpm": "8.15.1"
  },
I've added to my nextjs config:
Copy code
webpack(config) {
    return {
      // ... other webpack configurations
      resolve: {
        // ... other resolve configurations
        fallback: {
          "tls": false,
          "net": false,
        }
      }
    }
 },
Now I get the following:
Copy code
Warning: Reverting webpack devtool to 'eval-source-map'.
 Changing the webpack devtool in development mode will cause severe performance regressions.
 Read more: https://nextjs.org/docs/messages/improper-devtool
 Error: Cannot find module 'next/dist/build/webpack/plugins/terser-webpack-plugin'
s
The runtime is the nextjs runtime (see https://nextjs.org/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes) not the package definition. Also this looks to be an updated example of the webpack config workaround (https://github.com/vercel/next.js/discussions/61153#discussioncomment-8247594). It tries to prevent server component code from being included in compiled code that is sent to the client.
p
I have extended webpack to:
Copy code
webpack: (config, { nextRuntime }) => {
    if (typeof nextRuntime === "undefined") {
      config.resolve.fallback = {
        ...config.resolve.fallback,
        fs: false,
        net: false,
        tls: false,
        http2: false,
        dns: false
      };
    }
    return config;
  },
Which gets past all the MODULE_NOT_FOUND issues. But now I'm getting > Uncaught (in promise) TypeError: The "original" argument must be of type Function > at Object.promisify (util.js:1:38321) > Warning: An error occurred during hydration. The server HTML was replaced with client content in #document.
My FE code:
Copy code
"use client";
import { Button } from '@raikou/server';
import { createSchema } from '../mutations/authzed/createSchema';

export default function Authzed() {
  const doSomething = async() => {
    await createSchema();
  }

  return <>
    <Button onClick={doSomething}>Create Schema</Button>
    </>
}
Server Actions:
Copy code
import { v1 } from '@authzed/authzed-node';

export async function createSchema() {
  const client = v1.NewClient('mykey');

  const writeRequest = v1.WriteSchemaRequest.create({
    schema: `
      definition user {}
        
      definition document {
          relation writer: user
      
          relation reader: user
      
          permission edit = writer
      
          permission view = reader + edit
      }
    `,
  });

  // Write a schema.
  const res = await new Promise((resolve, reject) => {
    client.writeSchema(writeRequest, function (err, response) {
      if (err) reject(err);
      resolve(response);
    });
  });

  console.log(res);

  return res;
}
s
Looks like other server only code is being loaded client side. I think you best bet is to move authzed client code to an api route and call that endpoint directly instead. Unfortunately that means the authzed node client is not compatible with server actions. File an issue for server action compatibility though https://github.com/authzed/authzed-node/issues
p
Will do and thanks!