typescriptnext.jsappwrite

Next.js Appwrite "TypeError: Failed to construct 'URL'" but works when given directly


I am following along an YouTube video by JS Mastery on their HealthCare application using Next.js and Appwrite. I got my API keys from Appwrite cloud and added them to the .env.local file. But when I run my project, I get the following error,

TypeError: Failed to construct 'URL': Invalid URL
    at Users.create (users.mjs:77:17)
    at createUser (patient.actions.ts:6:37)
    at onSubmit (PatientForm.tsx:43:42)
    at eval (index.esm.mjs:2256:23)

The code for creating an user looks like this,

import { ID, Query } from "node-appwrite"
import { users } from "../appwrite.config"

export const createUser = async (user: CreateUserParams) => {
    try {
        const newUser = await users.create(
            ID.unique(), 
            user.email, 
            user.phone, 
            undefined, 
            user.name
        )
        console.log(newUser)

    } catch(error: any) {
        if (error && error?.code === 409) {
            const documents = await users.list([
                Query.equal('email', [user.email])
            ])

            return documents?.users[0]
        } else {
            console.log(error)
        }
    }
}

and the user is exposed from this code,

import * as sdk from "node-appwrite";

export const {
    NEXT_PUBLIC_ENDPOINT: ENDPOINT,
    PROJECT_ID,
    API_KEY,
    DATABASE_ID,
    PATIENT_COLLECTION_ID,
    DOCTOR_COLLECTION_ID,
    APPOINTMENT_COLLECTION_ID,
    NEXT_PUBLIC_BUCKET_ID: BUCKET_ID,
} = process.env;

const client = new sdk.Client();

client.setEndpoint(ENDPOINT!).setProject(PROJECT_ID!).setKey(API_KEY!);

export const databases = new sdk.Databases(client);
export const users = new sdk.Users(client);
export const messaging = new sdk.Messaging(client);
export const storage = new sdk.Storage(client);

the .env.local file,

PROJECT_ID=************
API_KEY=************************************
DATABASE_ID=************
PATIENT_COLLECTION_ID=************
DOCTOR_COLLECTION_ID=************
APPOINTMENT_COLLECTION_ID=************
NEXT_PUBLIC_BUCKET_ID=************
NEXT_PUBLIC_ENDPOINT=https://cloud.appwrite.io/v1

I've double checked the API values and they are what they should be. To check if the values are wrong I tried replacing the variables names with the actual .env values and that works fine.


client
    .setEndpoint("https://cloud.appwrite.io/v1")
    .setProject("***************")
    .setKey("*****************);

Is there anything I am missing? Please let me know how to solve this issue. Any help is appreciated. Thank you.

Link to youtube video


Solution

  • add "use server" on top of patients.actions.ts file. By adding "use server", you're telling Next.js that all the functions in this file should be executed on the server, never on the client. Server-side code can access all environment variables, including those not prefixed with NEXT_PUBLIC_. This is why your PROJECT_ID, API_KEY, and DATABASE_ID became accessible.

     "use server"
        
        import { ID, Query } from "node-appwrite";
        import { users } from "../appwrite.config";
        
        export const createUser = async (user: CreateUserParams) => {    
          try {
            const newuser = await users.create(
              ID.unique(),
              user.email,
              user.phone,
              undefined,
              user.name
            );
          } catch (error: any) {
            if (error && error?.code === 409) {
              const documents = await users.list([Query.equal("email", [user.email])]);
              return documents?.users[0];
            }
            console.error("An error occurred while creating a new user:", error);
          }
        };