Blog

Add A Powerful Codeless Backend To Webflow With Backendless

by on December 2, 2020

Integrate Webflow with Backendless Feature

Webflow is a no-code website builder that “empowers designers to build professional, custom websites in a completely visual canvas.” When you integrate a feature-rich no-code Backendless backend with your Webflow frontend, you get a visual relational database, user management, bulletproof security, highly-scalable serverless hosting, and much more.

A functional website often requires much more than just an impressive user interface. All sites are supported by their backend, including servers, data storage, user management, and in many cases, logic.

The more capable a site’s backend, the more effective the website will be and the better the user experience.

Webflow is one of the best no-code website builders out there, but what happens when you want to add app-like functionality to your site? What if you want the functionality of a Webflow frontend but the versatility of a powerful database and backend?

That’s where Backendless comes in.

With a huge assortment of pre-built APIs and the capability to build your own codeless APIs, Backendless easily fills in all the backend gaps in your Webflow project.

The Webflow-Backendless Stack

In this article, we’re going to walk you through the process of integrating the several basic Backendless functions into your Webflow app (click to jump to each section):

The above items merely scratch the surface of the benefits of connecting your Webflow app to Backendless. You will also gain access to no-code features such as:

To get started, you will need a Webflow account (free to start) and a Backendless account (register here for free).

User Registration With Backendless

User registration and login enable your app to personalize the user’s experience.

User login opens up the entire set of user management functions in Backendless. These include session management, password management, user roles, and relating users to other data objects.

User registration also opens up user engagement opportunities such as email messaging, push notifications, and in-app messaging.

Let’s get started.

For our example, we need two Input components with ID emailInput (Text Type: Email, Placeholder: Email) and passwordInput (Text Type: Password, Placeholder: Password), as well as a button with ID registerUserButton:

Unlike our previous integration articles, Webflow does not have it’s own codeless logic system. In order to add the logic we need, we will have to write some code.

All user registration logic will be written using JavaScript. We will add it in the Custom Code section:

Below is the entire code with step by step comments (denoted by lines starting with //). Where you see https://api.backendless.com/APP_ID/REST_API_KEY/users/register, replace APP_ID and REST_API_KEY with the values for your app (found on your Backend Dashboard in Backendless Console).

<script>

// get the UI Element objects whose ID properties match the specified string
// we'll get the email and password values from the corresponding fields to use in the request
const emailInput = document.getElementById('emailInput');
const passwordInput = document.getElementById('passwordInput');
const registerUserButton = document.getElementById("registerUserButton");

// handle the Register User Button click event
// when this button is clicked we'll call the registerUser() function
registerUserButton.addEventListener('click', (event) => {
  registerUser();
});

function registerUser() {

  // create the XMLHttpRequest to make the registration request to Backendless,
  // setup the necessary header "Content-Type":"application/json" and
  // necessary parameters email and password
  // more info about Backendless User Registration can be found here: 
  // https://backendless.com/docs/rest/users_user_registration.html

  const request = new XMLHttpRequest();
  request.open('POST', 'https://api.backendless.com/APP_ID/REST_API_KEY/users/register', true);
  request.setRequestHeader("Content-Type", "application/json");
  const data = { 'email': emailInput.value, 'password': passwordInput.value };
  request.send(JSON.stringify(data));
  
  // handle the request response here
  request.onreadystatechange = function () {
    if (request.readyState == 4) {
      const result = JSON.parse(request.response);
      // if registration is successful - show the alert about successful registration
      if (request.status === 200) {
        alert('Registration successful. You can now login as ' + result.email);
  }
  // if registration failed - show the error alert
  else {
    alert('Registration failed: ' + result.message);
  }

  // clear the Email and Password input fields
  emailInput.value = emailInput.defaultValue;
  passwordInput.value = passwordInput.defaultValue;
}
  };
};

</script>

Once you’ve added the code, we’ll test it out:

  1. Save changes (1),
  2. Publish the site (2),
  3. Open the link to the published site (3)

On the opened published site, enter the email and password of a new user and click Register User. If registration was successful, we will receive a message about successful registration:

If an error occurred during registration (for example, the user tried to register with an existing email address), then we will receive the following notification:

Login With Backendless

Now that we’ve had the user register, let’s create a login page.

For this page, we again need two Input components with ID loginInput (Text Type: Plain, Placeholder: Login) and passwordInput (Text Type: Password, Placeholder: Password), as well as a button with ID loginButton:

Once again, all login logic will be written using JavaScript in the Custom Code section:

Below is the entire code with step by step comments (denoted by lines starting with //). Where you see https://api.backendless.com/APP_ID/REST_API_KEY/users/login, replace APP_ID and REST_API_KEY with the values for your app (found on your Backend Dashboard in Backendless Console).

<script>

// get the UI Element objects whose ID properties match the specified string
// we'll get the login and password values from the corresponding fields to use in the request
const loginInput = document.getElementById('loginInput');
const passwordInput = document.getElementById('passwordInput');
const loginButton = document.getElementById("loginButton");

// handle the Login Button click event
// when this button is clicked we'll call the login() function
loginButton.addEventListener('click', (event) => {  
  login();
});


function login() {

  // create the XMLHttpRequest to make the login request to Backendless,
  // setup the necessary header "Content-Type":"application/json" and
  // necessary parameters login and password

  // more info about Backendless Login can be found here: 
  // https://backendless.com/docs/rest/users_login.html

  const request = new XMLHttpRequest();
  request.open('POST', 'https://api.backendless.com/APP_ID/REST_API_KEY/users/login', true);
  request.setRequestHeader("Content-Type", "application/json");
  const data = { 'login': loginInput.value, 'password': passwordInput.value };
  request.send(JSON.stringify(data));
  
  // handle the request response here
  request.onreadystatechange = function () {
    if (request.readyState == 4) {
      const result = JSON.parse(request.response);
      // if login is successful - save user-token and
      // show the alert about successful login
      if (request.status === 200) {
        const localStorage = window.localStorage;
        localStorage.setItem('user-token', result['user-token']);  
        alert('User has been logged in Backendless: ' + result.email);
      }
      // if login failed - show the error alert
      else {
        alert('Login failed: ' + result.message);
      }


      // clear the Login and Password input fields
      loginInput.value = loginInput.defaultValue;
      passwordInput.value = passwordInput.defaultValue;
    }
  };
};

</script>

Please note that after a successful login, we save the token of the logged-in user on the device so that it can be used in subsequent requests.

To test our code:

  1. Save changes (1),
  2. Publish the site (2),
  3. Open the link to the published site (3):

On the published website that opens, enter the login and password of an existing user and click Login. If the login was successful, we will receive a message about the success of the operation:

If an error occurred during login (for example, the user tried to login with an incorrect password), then we will receive the following notification:

Save Data Into Backendless Database

Backendless Database is what sets Backendless apart from every other no-code platform out there. Your database can store a wide range of data types (including spatial/geo data and JSON objects) and makes it trivially easy to create relations between objects.

Backendless Database uses a SQL-based querying system. (We will touch on that more in the next section.) This approach allows you to easily query your data and display exactly what you want the user to see.

To start working with our data, let’s first take a look at how to save data into our Backendless Database from Webflow. Let’s build a simple new page to try it out.

For this example we need two Input components with ID nameInput (Text Type: Plain, Placeholder: Name) and ageInput (Text Type: Number, Placeholder: Age), as well as a button with ID saveButton:

All the logic for saving the object will be written using JavaScript in the Custom Code section:

We will save the data to a table called Person in our Backendless Database.

Below is the entire code with step by step comments (denoted by lines starting with //). Where you see https://api.backendless.com/APP_ID/REST_API_KEY/data/Person, replace APP_ID and REST_API_KEY with the values for your app (found on your Backend Dashboard in Backendless Console).

<script>

// get the UI Element objects which ID properties match the specified string
// we'll get the name and age values from the corresponding fields to use in the request
const nameInput = document.getElementById('nameInput');
const ageInput = document.getElementById('ageInput');
const saveButton = document.getElementById("saveButton");

// handle the Save Button click event
// when this button is clicked we'll call the save() function
saveButton.addEventListener('click', (event) => {  
  save();
});

function save() {

  // create the XMLHttpRequest to make the save request to Backendless,
  // setup the necessary header "Content-Type":"application/json",
  // the user-token header if the user has previously been logged in and
  // the name and age parameters

  // more info about Backendless Object Saving can be found here: 
  // https://backendless.com/docs/rest/data_single_object_create.html

  const request = new XMLHttpRequest();
  request.open('POST', 'https://api.backendless.com/APP_ID/REST_API_KEY/data/Person', true);
  request.setRequestHeader("Content-Type", "application/json");

  // get userToken value from the local storage
  // we saved it in the previous section describing Login
  const userToken = localStorage.getItem('user-token');
  if (userToken) {
    request.setRequestHeader("user-token", userToken);
  }

  const data = { 'name': nameInput.value, 'age': Number(ageInput.value) };
  request.send(JSON.stringify(data));

  // handle the request response here
  request.onreadystatechange = function () {
    if (request.readyState == 4) {
      const result = JSON.parse(request.response);
      // if saving is successful show the alert about successful operation
      if (request.status === 200) {
        alert('Object has been saved in Backendless with objectId: ' + result.objectId);
      }

      // if saving operation failed - show the error alert
      else {
       alert('Saving failed: ' + result.message);
      }

      // clear the Login and Password input fields
      nameInput.value = nameInput.defaultValue;
     ageInput.value = ageInput.defaultValue;
    }
  };
};

</script>

Now let’s try it out. Save the changes, publish the site, and open it.

Enter the name and age of the object and click Save. If the save operation is successful, we will receive a message about the success of the operation:

Run A Query In Backendless

Finally, let’s put together a page to query our database and display the results.

For this example, we need an Input component with the ID whereClauseInput (Text Type: Plain, Placeholder: Where Clause) and a button with the ID findButton:

All the logic for selecting objects will be written using JavaScript in the Custom Code section:

We will be querying our Person table created in the previous section.

Below is the entire code with step by step comments (denoted by lines starting with //). Where you see https://api.backendless.com/APP_ID/REST_API_KEY/data/Person, replace APP_ID and REST_API_KEY with the values for your app (found on your Backend Dashboard in Backendless Console).

<script>

// get the UI Element objects which ID properties match the specified string
// we'll get the whereClause value from the corresponding field to use in the request
const whereClauseInput = document.getElementById('whereClauseInput');
const findButton = document.getElementById('findButton');
const tableId = 'resultsTable';

// handle the Find Button click event
// when this button is clicked we'll call the find() function
findButton.addEventListener('click', (event) => {  
  find();
});

function find() {
  // every time we click the Find Button we should clean (remove) the existing results table
  const resultsTable = document.getElementById(tableId);
  if (resultsTable) {
    const parentElement = resultsTable.parentElement;
    parentElement.removeChild(resultsTable);
  }

  // create a XMLHttpRequest to make the find request to Backendless\
  // more info about Advanced Object Retrieval can be found here: 
  // https://backendless.com/docs/rest/data_search_with_where_clause.html

  let url = 'https://api.backendless.com/APP_ID/REST_API_KEY/data/Person'
  const whereClause = whereClauseInput.value;
  if (whereClause) {
    url += '?where=' + encodeURI(whereClause);
  }

  const request = new XMLHttpRequest();
  request.open('GET', url);
  request.send();
    
  // handle the request response here
  request.onreadystatechange = function () {
    if (request.readyState == 4) {
      const results = JSON.parse(request.response);
      // if retrieval is successful - create and fill the table with results objects
      if (request.status === 200) {
        let objects = new Array();
        results.forEach((object) => {
          objects.push({ 'name': object.name, 'age': object.age });
        });
        createTable(objects, ['name', 'age'], ['Name', 'Age']);
      }
      // if the find operation failed - show the error alert
      else {
        alert('Object retrieval failed: ' + result.message);
      }

      // clear the Where Clause input field
      whereClauseInput.value = whereClauseInput.defaultValue;
    }
  };
};

function createTable(objectsArray, fields, fieldTitles) {
  // we'll add the table to the existing form (see the screenshot below)
  const body = document.getElementsByTagName('form')[0];

  // the code below creates the basic table for specified fields

  const table = document.createElement('table');
  table.setAttribute('id', tableId);
  table.style.border = "1px solid black";
  table.style.width="100%";

  const thead = document.createElement('thead');
  thead.style.border = "1px solid black";
  thead.style.backgroundColor = '#E0E0E0';

  const tr = document.createElement('tr');  

  fieldTitles.forEach((fieldTitle) => {
    const th = document.createElement('th');    
    th.appendChild(document.createTextNode(fieldTitle));
    tr.appendChild(th);
  });

  thead.appendChild(tr);
  table.appendChild(thead);

  const tbdy = document.createElement('tbody');
  objectsArray.forEach((object) => {
    const tr = document.createElement('tr');
    tr.style.backgroundColor = "#F5F5F5";
    tr.style.textAlign = 'center';

    fields.forEach((field) => {
      var td = document.createElement('td');
      td.appendChild(document.createTextNode(object[field]));
      tr.appendChild(td);
    });    

    tbdy.appendChild(tr);    
  });
  table.appendChild(tbdy);
  body.appendChild(table)
  return table;
}

</script>

Let’s try it out. Save the changes, publish the site, and open it.

First, let’s enter a where clause and click Find:

As a result of a query with whereClause = "age> 25", we got a list of Person table objects with age greater than 25. If we execute a Find query without specifying a whereClause, we get a list of all objects:


Closing

You should now have a basic handle on how to interact with a Backendless backend via Webflow, but this is just the tip of the iceberg. Adding a Backendless backend and database to a Webflow website gives your site app-level flexibility.

With Webflow’s beautiful frontend interface and Backendless’ database, backend and many pre-built APIs, your possibilities become endless.

In addition to managing users and data, Backendless gives you access to timers, event handlers, and whatever Codeless logic you can think of on the backend.

Your app is virtually limitless.

Thanks for reading and Happy Codeless Coding!

Leave a Reply