top of page

Calculate Distances using Wix Velo and Google Distance API


graphic green with text "Calculate distances using Wix Velo"

For developers aiming to enhance their Wix websites with dynamic data capabilities, implementing distance calculation using Wix Velo, in combination with Google's Distance Matrix API, presents a potent solution. This comprehensive guide is designed for developers adept in Wix Velo and Google Cloud services, detailing the steps to integrate these technologies effectively. It enables the execution of real-time distance calculations directly on your Wix site, leveraging the strengths of both platforms.


Step 1: Google Distance Matrix API Setup


Project & API Configuration:

  • Google Cloud Console: Begin by setting up a project in the Google Cloud Console. Ensure that billing is enabled for your project.

  • Enable the API: Navigate to the “APIs & Services” dashboard. Search for and enable the Distance Matrix API.

  • API Key Generation: Generate an API key in the 'Credentials' section. It’s crucial to restrict the API key to prevent unauthorized use.


Security Tips:

  • Use HTTP referrers to restrict where the API key can be used.

  • Regularly monitor the usage of your API key.


Step 2: Backend Implementation in Wix Velo


Setting Up the Backend Environment

  • Backend File Creation: In your Wix site editor, navigate to the backend section and create a new JavaScript file, for example, distanceMatrix.jsw. This file will host the server-side logic.

  • Understanding Serverless Functions in Velo: Wix Velo uses serverless functions (.jsw files) that run in a secure, managed backend environment. These functions can make API calls, process data, and communicate with the frontend.


Writing the API Interaction Function

1.Function Declaration:

  • Declare an asynchronous function, getDistance, which takes two parameters: origin and destination.

  • These parameters represent the starting and ending points for the distance calculation.

2. Building the API URL:

  • Construct the request URL for the Distance Matrix API.

  • Use encodeURIComponent to ensure that the input strings are correctly formatted for a URL.

3. API Key Management:

  • Store your API key securely. Avoid hardcoding it directly in the function.

  • Consider using Wix secrets manager or environment variables for storing the API key.

4. Making the API Call:

  • Use wix-fetch to make a GET request to the API.

  • Handle the promise returned by fetch using async-await syntax for better readability and error handling.

5. Error Handling:

  • Implement try-catch blocks to gracefully handle any errors during the API call.

  • Log errors for debugging and return a user-friendly message or fallback data.



import { fetch } from 'wix-fetch';
import { getSecret } from 'wix-secrets-backend';

export async function getDistance(origin, destination) {
    try {
        const apiKey = await getSecret("googleApiKey");
        const url = `https://maps.googleapis.com/maps/api/distancematrix/json?origins=${encodeURIComponent(origin)}&destinations=${encodeURIComponent(destination)}&key=${apiKey}`;

        const response = await fetch(url);
        const data = await response.json();

        // Handle the response data as needed
        return data;
    } catch (error) {
        console.error('Error fetching distance data:', error);
        throw new Error('Unable to fetch distance data');
    }
}

Best Practices and Considerations

  • API Key Security: Never expose your API key on the client side. Keeping it in the backend (.jsw file) is a safer practice.

  • Rate Limiting and Quotas: Be aware of the Google API's rate limits and quotas. Implement logic to handle these limits gracefully.

  • Data Parsing and Validation: Ensure to parse and validate the API response data. Handle different response scenarios (e.g., zero results, invalid requests).

  • Testing: Thoroughly test your backend function with various inputs to ensure it handles all cases effectively.


Step 3: Frontend Integration


Preparing the UI Components

Designing the Interface:

  • Create an intuitive layout on your Wix site that includes input fields for origin and destination, a submit button, and an area to display results.

  • Use Wix Editor to add and style these elements. Give each element a unique ID for easy reference in your code.

Enhancing User Interaction:

  • Consider adding dropdowns, auto-complete features, or interactive maps for a more user-friendly experience.

  • Ensure that the UI is responsive and accessible.

Interactivity with Velo Code

Setting up Event Listeners:

  • Use $w.onReady function to initialize your code once the page is fully loaded.

  • Add event listeners to the input fields and buttons to handle user actions.


Connecting to the Backend Function:

  • Import the getDistance function from the backend file.

  • Use this function to send requests to the backend when the user submits their input.

Implementing the Distance Calculation Logic

Retrieving User Input:

  • Capture the values from the origin and destination input fields.

  • Validate the input to ensure it’s in a usable format before sending it to the backend.

API Request and Handling Response:

  • Call the getDistance function with the user’s input.

  • Handle the promise returned by the function, extracting and processing the distance data.

Displaying the Results:

  • Present the distance information in the designated area of your page.

  • Format the data for readability (e.g., rounding off distances, converting units).


Error and Loading States:

  • Implement loading states to inform users that their request is being processed.

  • Handle any errors returned from the backend gracefully, displaying user-friendly error messages.


import { getDistance } from 'backend/distanceMatrix';

$w.onReady(function () {
    $w('#calculateButton').onClick(async () => {
        const origin = $w('#originInput').value;
        const destination = $w('#destinationInput').value;

        if (!origin || !destination) {
            // Handle empty input
            return;
        }

        try {
            $w('#resultsText').text = "Calculating...";
            const distanceData = await getDistance(origin, destination);

            // Process and display the data
            $w('#resultsText').text = `Distance: ${distanceData.rows[0].elements[0].distance.text}`;
        } catch (error) {
            $w('#resultsText').text = "Error fetching distance. Please try again.";
        }
    });
});

Best Practices and Advanced Features

  • User Feedback: Implement real-time feedback for user actions (e.g., invalid input, no results found).

  • Mobile Responsiveness: Test and ensure your UI is responsive on different devices.

  • Advanced Features: For more advanced implementations, integrate interactive maps or leverage Wix’s own location services for an enhanced user experience.



Step 4: Real world example


example of UI for address input field when paris is selected
example of UI for repeater displaying items and showing distance text

In this example, we will demonstrate how to efficiently sort items in a database based on the distance between a given origin and the addresses associated with each item. This process is crucial for applications that require location-based data sorting, such as service directories, delivery systems, or event planning platforms. Initially, we will focus on using an address input field entered by users. This traditional method allows users to manually input their location, from which the system calculates and sorts the database entries by proximity.


Afterwards, we'll enhance the functionality by integrating geolocation. This modern approach leverages the user's real-time location data, obtained directly from their device, to perform the sorting. By incorporating geolocation, we eliminate the need for manual address input, thus simplifying the user experience and providing more accurate, immediate results



1- Set up

  • Add the address input along side your filters.

  • Set up your repeater

  • Make the connections

example of UI for address input field and filters

2- Code


1. Setting Up the Backend

Reverse Geocoding Function

The reverseGeocode(lat, lng) function is essential for converting geographical coordinates into a readable address. It's particularly useful in applications where the user's coordinates need to be displayed or used in a more understandable format.

  • API Endpoint: The function constructs a URL for the Google Maps Geocoding API, embedding the latitude and longitude parameters.

  • API Key Management: Ensure your Google API key is securely stored and accessed. Avoid hardcoding it in your scripts.

  • Error Handling: Implement robust error handling to manage unexpected responses or issues with the API.


export async function reverseGeocode(lat, lng) {
    const endpoint = `https://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${lng}&key=${API_KEY}`;

    const response = await fetch(endpoint);
    const data = await response.json();

    if (data.status === "OK" && data.results.length > 0) {
        return data.results[0];
    }
    return null;
}

Distance Calculation Function

The getDistances(origin) function leverages the Google Distance Matrix API to calculate distances from a user's location to multiple destinations.


export async function getDistances(origin) {
    const originStr = `${origin.latitude},${origin.longitude}`;
    const results = await wixData.query("YourCollection").find();
    let items = results.items;

    // Preparing API request
    const destinations = items.map(item => item.adresse?.location ? `${item.adresse.location.latitude},${item.adresse.location.longitude}` : null).filter(Boolean);
    const apiUrl = `https://maps.googleapis.com/maps/api/distancematrix/json?origins=${originStr}&destinations=${destinations.join('|')}&key=${API_KEY}`;

    // API call and response handling
    try {
        const response = await fetch(apiUrl);
        const data = await response.json();
        if (data.status !== "OK") throw new Error(data.error_message || "API error");

        const distances = data.rows[0].elements;
        return items.map((item, index) => distances[index]?.distance ? {...item, distance: distances[index].distance.value / 1000} : item);
    } catch (error) {
        console.error("Error fetching distance", error);
        throw error;
    }
}
  • Data Preparation: It starts by fetching destination data from a Wix database collection and formatting it for the API request.

  • API Interaction: Constructs a request to the Distance Matrix API, which returns distance and travel time between points.

  • Data Processing: The function processes the API response, associating each distance with the corresponding destination.

  • Error Handling: Implement thorough error checking and handling to manage API response issues or data processing errors.


Distance Calculation: The getDistances(origin) function is a game-changer for businesses that need to calculate distances from a user's location to multiple destinations. By querying our Wix database and using the Google Maps Distance Matrix API, we provide real-time distance information, enhancing operational efficiency and user experience.


2. Implementing on the Frontend

Geolocation Function

Geolocation Function: The geolocalize_click(event) function obtains the user's current location and then calls the backend functions to fetch and display the distance data.


export function geolocalize_click(event) {
    wixWindow.getCurrentGeolocation().then(async (obj) => {
        const origin = { latitude: obj.coords.latitude, longitude: obj.coords.longitude };
        const VisitorAddress = await reverseGeocode(origin.latitude, origin.longitude);
        
        // Handle distance calculation and UI update
        if (VisitorAddress) {
            try {
                await getDistances(origin);
                // Additional UI and dataset logic here
            } catch (error) {
                console.error("Error in distance calculation", error);
            }
        } else {
            console.error("Address fetch failed");
        }
    }).catch(error => console.error("Geolocation error:", error));
}

  • User Permission: Always ensure to handle user permissions for accessing geolocation data sensitively and legally.

  • Backend Integration: This function interacts with the backend functions reverseGeocode and getDistances to process the user's location.

  • UI Updates: Based on the returned data, you can update the UI elements dynamically to reflect the distances or location information.


Address Input Change Handling

The Adressinput_change(event) function allows users to manually input a different address, which then recalculates the distances.


export async function Adressinput_change(event) {
    let origin = $w('#Adressinput').value.location;
    if (origin) {
        try {
            await getDistances(origin);
            // UI and dataset logic
        } catch (error) {
            console.error("Error in recalculating distances", error);
        }
    }
}
  • User Input Validation: Ensure that the address input by the user is validated before processing. This is done automatically by the address input field.

  • Dynamic Response: The function should dynamically update the distances and potentially the displayed results based on the new address.



Conclusion: Distance Calculation using Wix Velo

In conclusion, the integration of proximity-based sorting using both manual address input and geolocation in Wix Velo, complemented by the Google Distance Matrix API, represents a significant advancement in the realm of web applications. This dual approach caters to diverse user preferences, offering both the precision of manual address entry and the convenience of automatic geolocation. It's a robust solution that enhances user experience by providing accurate, location-specific data with minimal effort required from the user.


This implementation is not just a technical achievement; it's a step towards more intuitive and responsive web services. Whether for finding nearby services, calculating delivery times, or planning routes, this functionality streamlines operations and elevates user satisfaction. As technology continues to evolve, integrating such innovative solutions will be key for businesses looking to stay competitive and responsive to their customers' needs.


At CodeMasters, we're dedicated to helping businesses harness the power of advanced web technologies. If you're looking to enhance your website with sophisticated, user-centric features like proximity-based sorting, our team of experts is here to assist. Contact CodeMasters today to explore how we can elevate your digital presence and deliver exceptional experiences to your users.





bottom of page