Velo Web Modules: Calling Backend Code from the Frontend

Warning: The .jsw web module file extension is deprecated and you will soon be unable to create a new .jsw file. However, .jsw web modules will continue to be supported in existing sites.

Introduction to web modules

Web modules are backend files defined by either a .web.js or .jsw extension. They allow you to write web module functions that run server-side, and easily call them in your client-side code. With web modules, you can import backend functions into page code or public files, knowing they will run safely in the backend. Velo handles all the necessary client-server communication to enable this access. See the advanced tip below if you want to know how this communication is handled.

To add a web module to your site:

  1. Hover over the Backend heading in the Public & Backend section of the Code sidebar (Wix Studio) or the Velo sidebar (Wix Editor).
  2. Click the plus icon and then click Add web module. This creates a web module with a .web.js extension.
Advanced: How Web Modules Work - Behind the Scenes

When you import a web module on the client-side you get a proxy function to the web module function. This proxy function uses an XMLHttpRequest to invoke the function in the backend. The runtime listens to those invocations and calls the appropriate function.

The arguments and return value are serialized using JSON.

Syntax & permissions

Web module files must have one of the following file extensions: .web.js or .jsw.

Because web modules allow you to call your backend functions from the frontend, it's important to restrict visitor access to their functionality. You can do so by setting permissions, thereby controlling which users can interact with backend code either through your site's functionality or through a browser's developer tools. Permission options include Admin, Site Member, and Anyone. The syntax for exporting functions and setting permissions for your functions differ based on the web module file extension in use. Learn more about web module permissions.

.web.js file

To export your backend web module functions and to set their permissions, you must use web methods in addition to the export keyword. A web method is a wrapper function that defines an exported function and sets its permissions. Web methods are required to export functions from .web.js files. Additionally, web methods do not work in files without the web.js extension.

Web methods are defined by importing the webMethod() function and the Permissions enum from the 'wix-web-module'. The webMethod() function takes 2 arguments: a permission and the function you want to export. Here is an example defining a backend function in a .web.js file.

Copy
1
```javascript
2
//Filename: multiplication.web.js
3
import {Permissions, webMethod} from 'wix-web-module';
4
5
export const multiply = webMethod(Permissions.Anyone, (a,b) => a * b);
6
```

.jsw files (deprecated)

To export your backend web module functions, simply add the javascript export keyword before declaring your functions. Exported functions within a .jsw file have default permissions set to Anyone. You can override the default permissions using the UI. Here is an example defining a backend function in a .jsw file.

Copy
1
```javascript
2
// Filename: multiplication.jsw
3
export function multiply(factor1, factor2) {
4
return factor1 * factor2;
5
}
6
```

Hello world example

Note: When using an exported function from the frontend, ensure the import statement matches the correct file. For .web.js modules, remember to add .web at the end of the file name in the import statement.

The following example shows how you can call a backend function in your client-side code:

Copy
1
import { rotatingGreeting } from 'backend/helloModule.web';
2
3
$w.onReady(function () {
4
let callCount = 0;
5
6
$w('#button').onClick(async () => {
7
$w('#responseText').text = await rotatingGreeting(callCount++);
8
$w('#responseText').show();
9
});
10
});

Note: The code example above imports the rotatingGreeting() function from the backend/helloModule.web file. If you are importing functions from the .jsw file, use the following import statement: import {rotatingGreeting} from 'backend/helloModule';

When to use web modules

Web module functions contain code you would typically want or need to run in the backend. Your code may have security risks if it runs in the frontend, or you may want to access other web services. For example, let's say you want to enable your site visitor to send an email via a 3rd-party provider. You would store your API key to the 3rd-party service in the Secrets Manager, and write your function that sends the email in the backend.

.web.js file

Copy
1
// Filename: backend/sendEmail.web.js
2
3
import { Permissions, webMethod } from 'wix-web-module';
4
import { getSecret } from 'wix-secrets-backend';
5
import { fetch } from 'wix-fetch';
6
// wix-fetch is the API we provide to make https calls in the backend
7
8
export const sendEmail = webMethod(
9
Permissions.Anyone,
10
async (address, subject, body) => {
11
const API_KEY = await getSecret('<SECRET_NAME>');
12
13
return fetch("https://a-backend-service-that-sends-email.com/send?APIKey=" + API_KEY, {
14
method: 'post',
15
body: JSON.stringify({ address, subject, body })
16
}).then(function (response) {
17
if (response.status >= 200 && response.status < 300)
18
return response.text();
19
else
20
throw new Error(response.statusText);
21
});
22
});

.jsw file (deprecated)

Copy
1
// Filename: backend/sendEmail.jsw
2
3
import {getSecret} from 'wix-secrets-backend';
4
import {fetch} from 'wix-fetch';
5
// wix-fetch is the API we provide to make https calls in the backend
6
7
const API_KEY = await getSecret(<SECRET_NAME>);
8
export function sendEmail (address, subject, body) {
9
return fetch("https://a-backend-service-that-sends-email.com/send?APIKey=" + API_KEY, {
10
method: 'post',
11
body: JSON.stringify({address, subject, body})
12
}).then(function(response) {
13
if (response.status >= 200 && response.status < 300)
14
return response.text();
15
else
16
throw new Error(response.statusText);
17
});
18
};

The code examples above needs to be run in the backend for two reasons:

  1. It includes your sensitive information, such as a reference to your API key to the 3rd-party service. You don't want to expose this to the client.
  2. You are calling a 3rd-party web service, which you can only do in the backend because of cross-origin resource sharing (CORS).

You would then import the function from your .web.js or .jsw web module into your frontend file to use it:

Copy
1
import {sendEmail} from 'backend/sendEmail.web';
2
3
export function sendButton_onClick(event) {
4
sendEmail(
5
$w("#addressInput").value,
6
$w("#subjectInput").value,
7
$w("#bodyInput").value)
8
.then(function() {
9
console.log("email was sent");
10
});
11
}

Note: The code example above imports the sendEmail() function from the backend/sendEmail.web file. If you are importing functions from the .jsw file, use the following import statement: import {sendEmail} from 'backend/sendEmail';

Using web module functions in backend

You can also import web module functions into other modules in the backend.

Calling a function in a web module

Unlike regular modules that allow you to export functions, objects, and other items, you can only export functions from web modules. Web modules also always return a promise. This is true even if, in the implementation of the function, it returns a value. For example, if your web module function returns a value, like this:

.web.js file

Copy
1
//Filename: aModule.web.js
2
import {Permissions, webMethod} from 'wix-web-module';
3
4
export const multiply = webMethod(Permissions.Anyone, (a,b) => a * b);

.jsw file (deprecated)

Copy
1
// Filename: aModule.jsw
2
export function multiply(factor1, factor2) {
3
return factor1 * factor2;
4
}

When you call the function, it still returns a promise that resolves to the value. So you need to use it like this:

Copy
1
import {multiply} from 'backend/aModule.web';
2
3
multiply(4,5).then(function(product) {
4
console.log(product);
5
// Logs: 20
6
});

Note: The example above imports the multilply() function from the backend/aModule.web file. If you are importing functions from the .jsw file, use the following import statement: import {multiply} from 'backend/aModule';

Debugging web modules

You can log messages to the console in web modules and they will be displayed in the client's console log when previewing the site, even though the code is running in the backend.

Was this helpful?
Yes
No