--- title: "Configure the client" url: https://docs.catalyst.zoho.com/en/tutorials/leadmanager/java/configure-client-directory/ description: "Build a Lead Manager application that connects to your Zoho CRM account using Catalyst connector, and enables you to view, create, update, or delete leads from the Leads module directly" last_updated: 2026-08-28T07:59:38Z service: All Services type: tutorial related_links: - name: "Client Directory Structure" url: /en/cli/v1/project-directory-structure/introduction - name: "Web Client Hosting" url: /en/cloud-scale/help/web-client-hosting/introduction/ --- # Configure the Client Directory Let's now configure the client component. The [client directory](https://docs.catalyst.zoho.com/en/cli/v1/project-directory-structure/introduction) contains: * The `index.html` file that contains the HTML code for the frontend application * The `main.css` file that contains the CSS code * The `main.js` file that contains the JavaScript code * The `client-package.json` configuration file We will be coding `index.html`, `main.js` and `main.css`. We will also create a new file `login.html` in this directory and add code in it. > **Note:** Please go through the code in this section to make sure you fully understand it. We will discuss the code at the end of this section. Copy the code below and paste it in the respective files located in the `client/` directory of your project using an IDE and save the files. **index.html** ```xml <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>CRM Lead Manager</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" type="text/css" media="screen" href="main.css" /> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet"> <link href="https://cdnjs.cloudflare.com/ajax/libs/mdbootstrap/4.19.1/css/mdb.min.css" rel="stylesheet"> <script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"> </script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"> </script> <script src="main.js"></script> <script src="https://static.zohocdn.com/catalyst/sdk/js/4.6.2/catalystWebSDK.js"></script> <script src="/__catalyst/sdk/init.js"></script> <link href="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css"> <style> #connect { height: 260px; width: 500px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; margin: auto; } </style> </head> <body onload="getUserDetails()"> <br> <center> <h1>CRM Lead Manager</h1><br> </center> <div id="connect"> <center> <p>Click here to connect to Zoho CRM</p> <button onclick='navigate()'> <img src="https://www.zohowebstatic.com/sites/default/files/styles/product-home-page/public/icon-crm_blue.png" style="width: 180px;height: 130px;"> </button> </center> </div> <div style="width: 200px;float: right; margin-right: 30px;"><label for="logoutbtn" class="btn btn-success btn-block btn-outlined">Logout</label> <button id="logoutbtn" onclick="logout()" style="display: none;"></button> </div> <div id="main"> <div class="container"> <ul class="nav nav-tabs nav-justified mb-3" id="myTab" role="tablist"> <li class="nav-item"> <a class="nav-link active" id="check-tab" data-toggle="tab" href="#check" role="tab" aria-controls="check" aria-selected="true">Add a Lead</a> </li> <li class="nav-item"> <a class="nav-link" id="report-tab" data-toggle="tab" href="#report" onclick="getLeads()" role="tab" aria-controls="report" aria-selected="false">Manage Leads</a> </li> </ul><br> <div class="tab-content" id="myTabContent"> <div class="tab-pane fade show active" id="check" role="tabpanel" aria-labelledby="check-tab"> <div class="tab-pane fade show active" id="ex3-tabs-1" role="tabpanel" aria-labelledby="ex3-tab-1"> <div style="margin-left: 100px; margin-right:100px;"> <form id="leads"> <!-- 2 column grid layout with text inputs for the first and last names --> <div class="row mb-4"> <div class="col"> <div class="form-outline"> <label class="form-label" for="form6Example1">First name</label> <input type="text" id="firstName" class="form-control" /> </div> </div> <div class="col"> <div class="form-outline"> <label class="form-label" for="form6Example2">Last name</label> <input type="text" id="lastName" class="form-control" required /> </div> </div> </div> <!-- Text input --> <div class="form-outline mb-4"> <label class="form-label" for="form6Example3">Company name</label> <input type="text" id="companyName" class="form-control" /> </div> <!-- Email input --> <div class="form-outline mb-4"> <label class="form-label" for="form6Example5">Email</label> <input type="email" id="email" class="form-control" /> </div> <!-- Text input --> <div class="form-outline mb-4"> <label class="form-label" for="form6Example4">State</label> <input type="text" id="state" class="form-control" /> </div> <!-- Number input --> <div class="form-outline mb-4"> <label class="form-label" for="form6Example6">Phone</label> <input type="number" id="phone" class="form-control" /> </div> <!-- Number input --> <div class="form-outline mb-4"> <label class="form-label" for="form6Example6">Lead Source</label> <input type="text" id="leadSource" class="form-control" /> </div> <!-- Submit button --> <center><button type="submit" onclick="createLead();return false;" class="btn btn-primary btn-block mb-4" style="width: 100px;">Add Lead</button> <div id="loader" style="display: none;"> <div class="spinner-border" role="status"> <span class="sr-only">Loading...</span> </div> </div> </center> </form> </div> </div> </div> <div class="tab-pane fade" id="report" role="tabpanel" aria-labelledby="report-tab"> <center> <div id="loaders" style="display: none; padding-top: 200px;"> <div class="spinner-border" role="status"> <span class="sr-only">Loading...</span> </div> </div> </center> <p id="showData"></p> </div> </div> </div> <!-- Modal --> <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="vertical-alignment-helper"> <div class="modal-dialog vertical-align-center"> <div class="modal-content"> <center> <h4 class="modal-title" id="myModalLabel"></h4> <div class="modal-body" id="message"></div> <div class="modal-footer"> <button type="button" style="background-color: #007bff;color: white;" class="btn btn-default" data-dismiss="modal">Close</button> </div> </center> </div> </div> </div> </div> <div class="modal fade" id="editForm" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="vertical-alignment-helper"> <div class="modal-dialog vertical-align-center"> <div class="modal-content"> <div style="margin-left: 80px; margin-right:80px;"> <br> <center> <h2>Edit Lead</h2> </center> <br> <form id="editLeads"> <!-- 2 column grid layout with text inputs for the first and last names --> <div class="row mb-4"> <div class="col"> <div class="form-outline"> <label class="form-label" for="form6Example1">First name</label> <input type="text" id="editfirstName" class="form-control" /> </div> </div> <div class="col"> <div class="form-outline"> <label class="form-label" for="form6Example2">Last name</label> <input type="text" id="editlastName" class="form-control" required /> </div> </div> </div> <!-- Text input --> <div class="form-outline mb-4"> <label class="form-label" for="form6Example3">Company name</label> <input type="text" id="editcompanyName" class="form-control" /> </div> <!-- Email input --> <div class="form-outline mb-4"> <label class="form-label" for="form6Example5">Email</label> <input type="email" id="editemail" class="form-control" /> </div> <!-- Text input --> <div class="form-outline mb-4"> <label class="form-label" for="form6Example4">State</label> <input type="text" id="editstate" class="form-control" /> </div> <!-- Number input --> <div class="form-outline mb-4"> <label class="form-label" for="form6Example6">Phone</label> <input type="number" id="editphone" class="form-control" /> </div> <!-- Submit button --> <center><button type="submit" id="editBtn" onclick="editLead();return false;" class="btn btn-primary btn-block mb-4" style="width: 100px;">Edit</button> <div id="loader" style="display: none;"> <div class="spinner-border" role="status"> <span class="sr-only">Loading...</span> </div> </div> </center> </form> </div> </div> </div> </div> </div> <div class="modal fade right" id="ModalDanger" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog modal-notify modal-danger modal-side modal-top-right" role="document"> <!--Content--> <div class="modal-content"> <!--Header--> <div class="modal-header"> <p class="heading">Lead Deletion</p> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true" class="white-text">×</span> </button> </div> <!--Body--> <div class="modal-body"> <div class="row"> <div class="col-9"> <p>Are you sure you want to delete the Lead?</p> </div> </div> </div> <!--Footer--> <div class="modal-footer justify-content-center"> <a type="button" class="btn btn-danger" id="delete-btn" onclick="deleteLead()">Delete</a> <a type="button" class="btn btn-outline-danger waves-effect" data-dismiss="modal">Cancel</a> </div> </div> <!--/.Content--> </div> </div> </div> </body> <script> //Add Your Client ID and Redirect URL here function navigate() { window.location.href = "https://accounts.zoho.com/oauth/v2/auth?scope=ZohoCRM.modules.ALL&client_id={{YOUR_CLIENT_ID}}&response_type=code&access_type=offline&redirect_uri="+location.protocol + '//' + location.host + "/server/crmcrud/generateToken"; } </script> </html> ``` > **Note:** After adding `index.html` to your client folder, make sure to replace **{{YOUR_CLIENT_ID}}** in the `navigate()` function with your actual Zoho Client ID. **main.js** ```javascript function createLead() { debugger; $("#loader").show(); var firstName = $("#firstName").val(); var lastName = $("#lastName").val(); if (lastName == "") { alert("Kindly Enter the Last Name"); $("#loader").hide(); return; } var companyName = $("#companyName").val(); var email = $("#email").val(); var state = $("#state").val(); var phone = $("#phone").val(); var leadSource = $("#leadSource").val(); $.ajax({ url: "/server/crmcrud/crmData", type: "post", contentType: "application/json", data: JSON.stringify({ "First_Name": firstName, "Last_Name": lastName, "Company": companyName, "Email": email, "State": state, "Phone": phone, "Lead_Source": leadSource, }), success: function (data) { debugger; $('#leads').trigger("reset"); $("#myModalLabel").html(" Success"); $("#message").html("Lead Created Successfully"); $("#loader").hide(); $('#myModal').modal('show'); }, error: function (error) { $('#leads').trigger("reset"); $("#myModalLabel").html(" Failure"); $("#message").html("Please try again after Sometime"); $("#loader").hide(); $('#myModal').modal('show'); } }); } function logout() { var redirectURL = "http://localhost:3000/app/login.html"; //Add your app domain var auth = catalyst.auth; auth.signOut(redirectURL); } function getUserDetails() { $("#main").hide(); $("#connect").hide(); catalyst.auth.isUserAuthenticated().then(result => { $("#loader").show(); $.ajax({ url: "/server/crmcrud/getUserDetails", type: "get", success: function (data) { $("#loader").hide(); if (data.userId) { $("#main").show(); $("#connect").hide(); } else { $("#connect").show(); $("#main").hide(); } }, error: function (error) { $("#myModalLabel").html(" Failure"); $("#message").html("Please try again after Sometime"); $("#loader").hide(); $('#myModal').modal('show'); } }); }).catch(err => { document.body.innerHTML = 'You are not logged in. Please log in to continue. Redirecting you to the login page..'; setTimeout(function () { window.location.href = "login.html"; }, 3000); }); } function getLeads() { debugger; var tableContainer = document.getElementById("showData"); tableContainer.innerHTML = ""; $("#loaders").show(); $.ajax({ url: "/server/crmcrud/crmData", type: "get", success: function (data) { debugger; var reqData = getRequiredData(data.data); $("#loaders").hide(); renderTable(reqData); }, error: function (error) { $("#myModalLabel").html(" Failure"); $("#message").html("Please try again after Sometime"); $("#loader").hide(); $('#myModal').modal('show'); } }); } function showDeletePopup(leadID) { $('#ModalDanger').modal('show'); var deleteBtn = document.getElementById("delete-btn"); deleteBtn.value = leadID; } function deleteLead() { var leadID = document.getElementById('delete-btn').value; $.ajax({ url: "/server/crmcrud/crmData/" + leadID, type: "delete", success: function (data) { debugger; $('#ModalDanger').modal('toggle'); $("#myModalLabel").html(" Success"); $("#message").html("Lead Deleted Successfully"); $('#myModal').modal('show'); setTimeout(function () { location.reload(); }, 3000); }, error: function (error) { $("#myModalLabel").html(" Failure"); $("#message").html("Please try again after Sometime"); $("#loader").hide(); $('#myModal').modal('show'); } }); } function showEditPopup(leadID) { $.ajax({ url: "/server/crmcrud/crmData/" + leadID, type: "get", success: function (data) { debugger; var respData = data.data; $('#editfirstName').val(respData[0].First_Name); $('#editlastName').val(respData[0].Last_Name); $('#editcompanyName').val(respData[0].Company); $('#editemail').val(respData[0].Email); $('#editstate').val(respData[0].State); $('#editphone').val(respData[0].Phone); $('#editleadSource').val(respData[0].Lead_Source); $('#editBtn').val(respData[0].id); $('#editfirstName').html(respData[0].First_Name); $('#editlastName').html(respData[0].Last_Name); $('#editcompanyName').html(respData[0].Company); $('#editemail').html(respData[0].Email); $('#editstate').html(respData[0].State); $('#editphone').html(respData[0].Phone); $('#editleadSource').html(respData[0].Lead_Source); $('#editForm').modal('show'); }, error: function (error) { $("#myModalLabel").html(" Failure"); $("#message").html("Please try again after Sometime"); $("#loader").hide(); $('#myModal').modal('show'); } }); } function editLead() { var firstName = $("#editfirstName").val(); var lastName = $("#editlastName").val(); if (lastName == "") { alert("Kindly Enter the Last Name"); return; } var companyName = $("#editcompanyName").val(); var email = $("#editemail").val(); var state = $("#editstate").val(); var phone = $("#editphone").val(); var leadSource = $("#editleadSource").val(); var leadID = $("#editBtn").val(); $.ajax({ url: "/server/crmcrud/crmData/" + leadID, type: "put", contentType: "application/json", data: JSON.stringify({ "First_Name": firstName, "Last_Name": lastName, "Company": companyName, "Email": email, "State": state, "Phone": phone, "Lead_Source": leadSource }), success: function (data) { debugger; $('#editForm').modal('toggle'); $("#myModalLabel").html(" Success"); $("#message").html("Lead Edited Successfully"); $('#myModal').modal('show'); setTimeout(function () { location.reload(); }, 3000); }, error: function (error) { $('#leads').trigger("reset"); $("#myModalLabel").html(" Failure"); $("#message").html("Please try again after Sometime"); $("#loader").hide(); $('#myModal').modal('show'); } }); } function getRequiredData(data) { var i; var resp = []; for (i = 0; i < data.length; i++) { var gulp = { "First Name": data[i].First_Name, "Last Name": data[i].Last_Name, "Phone": data[i].Phone, "Email": data[i].Email, "Company": data[i].Company, "Edit": '<center><a href="javascript:showEditPopup(\'' + data[i].id + '\')">✎︎</a></center>', "Delete": '<center><a href="javascript:showDeletePopup(\'' + data[i].id + '\')">🗑︎</a></center>' } resp.push(gulp); } console.log(resp); return resp; } function renderTable(respData) { var col = []; for (var i = 0; i < respData.length; i++) { for (var key in respData[i]) { if (col.indexOf(key) === -1) { col.push(key); } } } var table = document.createElement("table"); table.id = "dataTable"; var tr = table.insertRow(-1); for (var i = 0; i < col.length; i++) { var th = document.createElement("th"); th.innerHTML = col[i]; tr.appendChild(th); } for (var i = 0; i < respData.length; i++) { tr = table.insertRow(-1); for (var j = 0; j < col.length; j++) { var tabCell = tr.insertCell(-1); tabCell.innerHTML = respData[i][col[j]]; } } var divContainer = document.getElementById("showData"); divContainer.innerHTML = ""; divContainer.appendChild(table); } ``` **main.css** ```css #dataTable { font-family: Arial, Helvetica, sans-serif; border-collapse: collapse; width: 100%; } #dataTable td, #dataTable th { border: 1px solid #ddd; padding: 8px; } #dataTable tr:nth-child(even){background-color: #f2f2f2;} #dataTable tr:hover {background-color: #ddd;} #dataTable th { padding-top: 12px; padding-bottom: 12px; text-align: left; background-color: #007bff; color: white; } .vertical-alignment-helper { display: table; height: 100%; width: 100%; pointer-events: none; } .vertical-align-center { display: table-cell; vertical-align: middle; pointer-events: none; } .modal-content { width: inherit; max-width: inherit; height: inherit; margin: 0 auto; pointer-events: all; } ``` **login.html** ```xml <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>CRM Lead Manager</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Bootstrap --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <!-- Catalyst SDK --> <script src="https://static.zohocdn.com/catalyst/sdk/js/4.6.2/catalystWebSDK.js"></script> <script src="/__catalyst/sdk/init.js"></script> <style> html, body { height: 100%; margin: 0; padding: 0; overflow: hidden; /* No page scroll */ background-color: #f8f9fa; font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; } body { display: flex; flex-direction: column; justify-content: center; align-items: center; } h1 { margin-bottom: 30px; color: #333; } /* Bigger height to avoid internal iframe scroll */ #login { width: 90%; max-width: 500px; height: 500px; /* increased from 260px */ overflow: hidden; /* hides any internal scrollbars */ border-radius: 8px; background: #fff; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); padding: 20px; } </style> </head> <body> <h1>CRM Lead Manager</h1> <div id="login"></div> <script> // Initialize Catalyst login widget catalyst.auth.signIn("login"); </script> <!-- Optional JS dependencies --> <script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script> </body> </html> ``` The client directory is now configured. Let us quickly go through the working of the function and client components of the application: * The `login.html` file in the client component enables Catalyst Authentication login. This does not handle the Zoho sign-in feature, only the Catalyst login. * `index.html` contains the code for the front-end of the client. It defines a function `navigate()` that enables the connection to the CRM account by passing the required authorization information such as the Client ID and the scope. * The Advanced I/O function defines the following APIs that perform various actions: * **`/generateToken`:** Obtains the Refresh Token by calling the `getRefreshToken()` function, and inserts it along with the `userID` of the current user in the _Token_ table in the Data Store. It then redirects to the index page of the client. * **`/getUserDetails`:** Fetches the user details by calling the `getUserDetails()` function. If there is no record in the table, a JSON response with the `userID` alone is sent. If the record exists in the table, it is sent along with the `userID`. * **`/crmData`:** This route defines the path of all leads in the Leads module. The Node function executes the HTTP `GET` and `POST` operations to fetch all leads or create a new lead using this route respectively. * **`/crmData/:id`:** This route defines the path of a particular lead in the Leads module. The `id` represents the unique ID of the lead in CRM. The function executes the HTTP `PUT` and `DELETE` operations to edit or delete a lead respectively using this route. * The Advanced I/O function contains the following functions that are called by the APIs: * **`getRefreshToken()`:** Fetches the Refresh Token by passing the Client ID, Client Secret, Redirect URI and other required values as query string parameters * **`getAccessToken()`:** Fetches the Access Token by passing the Refresh Token queried from the Token table using ZCQL, and other required parameters. The Access Token is fetched each time an operation needs to be performed on the CRM module, such as adding a lead or editing a lead. * **`getResponse()`:** Passes the Access Token fetched to obtain the authorization needed to perform each action on the CRM module. This function is called with each `/crmData` and `/crmData/:id` API to authorize the request. * **`getUserDetails()`:** Fetches the record from the _Token_ table that contains the Refresh Token, by passing the userID * `main.js` is the JavaScript function in the client component that parses the JSON responses obtained from the function and renders them in the `index.html` page. This function defines the actions for all the UI elements in the client application. For example, `getLeads()` obtains all leads from the function response and renders them in the client, and `showEditPopup()` defines the actions for editing a lead.