# Creating new apps To set up a new app in the Wized configurator, follow these steps: ![apps-panel-overview](apps-panel-overview.png) 1. **Access the apps panel:** Click on the [apps](/wized-configurator/left-sidebar/) icon on the left sidebar. 2. **Click on `+`** icon at the top right of the apps panel. Then, the right app settings panel will open 3. **Setting up the app:** - **Name:** Provide a clear and descriptive name for your app to ensure easy identification. - **App:** In this dropdown, you can see the native integrations that Wized has, or the `REST` option which you should choose if you want to integrate any other Web service. ## What to do based on your app type? ### Supabase Supabase is a native integration, so you only need to add the `URL` and `key` it's that simple! If you're unsure how to get these values, this video will guide you through the process ### Firebase Firebase is a native integration, so you only need to add the `Project ID`, `app ID`, `API Key` it's that simple! If you're unsure how to get these values, this video will guide you through the process ### Memberstack Memberstack is a native integration, so you only need to add the `Public Key` it's that simple! ### Airtable Airtable is a native integration, so you only need to click on `Connect Airtable` it's that simple! ![airtable](airtable.png) ### REST integration Specify the `base URL` of the API you are integrating. ![rest](rest.png) ::: info Note - For this example, we are using this [public API](https://pokeapi.co/) - Be sure to put only the base URL, you should not add the endpoint. ::: # Intro to the apps In Wized, the term `Apps` refers to the various APIs integrations that you will utilize throughout your project. Each App corresponds to a specific integration, and it is essential to create one App for each integration, as each [request](/requests/) made represents a different endpoint. Wized comes equipped with a range of native integrations, such as [Memberstack](https://www.memberstack.com/), [Supabase](https://supabase.com/), [Firebase](https://firebase.google.com/), and [Airtable](https://airtable.com/), which streamline the connection process by requiring only necessary credentials and configuration settings. ### App types in Wized - **Native integrations:** These are pre-configured connections to popular services that simplify the integration process. You only need to provide essential information to establish a connection with these services. - **Custom REST integrations:** If your project involves connecting to an external web service that provides a REST API, you can define the base URL and other request details as needed. # Basic concepts ## APIs ### What are APIs? APIs (Application Programming Interfaces) are like messengers that allow different applications to communicate and exchange information with each other. Think of them as a set of rules that facilitate communication between different systems, like a common language that computers understand. In the context of Wized, APIs allow you to connect your Webflow project to external services, such as databases, payment gateways, email delivery platforms, and more. This gives you the ability to access functionality and data that is not directly available in Wized, extending the capabilities of your web application. ### Why are APIs important? APIs are fundamental to developing modern web applications, as they allow you to: - **Save time and resources:** Instead of developing all the functionalities from scratch, you can take advantage of the work of other developers and companies that offer ready-to-use APIs. - **Enrich your app:** APIs allow you to add advanced and custom features to your app, such as online payments, email notifications, interactive maps, social media integration, and more. - **Access real-time data:** You can obtain up-to-date information from external services, such as product prices, news, sports scores, or any other type of data relevant to your application. - **Create automated workflows:** You can set up actions that trigger automatically in response to specific events, such as sending a welcome email when a new user registers or updating data in an external database. ### How do APIs work in Wized? Wized allows you to interact with external APIs through **API requests**. These requests are like messages you send to the API, specifying what information you need or what action you want to perform. The API processes your request and responds to you with the requested data or with a confirmation or error message. To set up an API request in Wized, you need to set up the following: - **Endpoint:** The specific web address of the service you want to access (for example, ). - **HTTP Method:** The type of action you want to perform (GET to get information, POST to send data, etc.). - **Headers (optional):** Additional information about your request, such as the type of data you expect to receive or authentication credentials. - **Body (optional):** The data you want to send to the API, usually in JSON format. ### How to read API documentation and use it in Wized? Each API has its own documentation explaining how to interact with it. When reading the documentation, pay attention to: - **Available Endpoints:** Identify the different routes or endpoints that the API offers and what type of information you can obtain or send through each one. - **Allowed HTTP Methods:** Check which HTTP methods (GET, POST, etc.) you can use for each endpoint. - **Parameters and Body:** Determines which query parameters or data in the body you should include in your requests to obtain the desired results. - **Required Headers:** Some APIs require specific headers for authentication or to indicate the format of the data. - **Response Structure:** Understand how the API returns information, usually in JSON format, so you can process it correctly in Wized. # DOM (Document Object Model) The DOM is a tree-like representation of the structure of a web page. In Wized, you can use JavaScript to interact with the DOM, allowing you to modify page elements, add or remove content, and respond to user events dynamically. # JSON (JavaScript Object Notation) JSON is a lightweight format for exchanging data between different systems. At Wized, JSON is widely used to represent structured data, such as the results of API requests or information stored in the database. # Reactivity Responsiveness is one of the core pillars of Wized, allowing you to create web applications that feel alive and respond immediately to changes in data and user interactions. ## What is reactivity? In simple terms, reactivity means that your app updates automatically without the need to reload the entire page. Imagine you are viewing a list of products in an online store, and you apply a filter to show only the items on sale. In a reactive app, the list would instantly update to show only the filtered products, without you having to wait for the page to reload. ## Why is reactivity important in Wized? Responsiveness is essential to creating a fluid and modern user experience. By eliminating page reloads and updating only the necessary parts of the interface, Wized allows you to: - **Improve your app’s speed and performance:** Real-time updates make your website feel faster and more responsive, improving the overall user experience. - **Create more dynamic and engaging interactions:** Elements on your page can instantly change and adapt to user actions, such as clicking a button, selecting an option from a menu, or submitting a form. - **Display up-to-date information in real time:** You can integrate data from external APIs or your own backend to display up-to-date information in real time, such as product prices, notifications, or search results. ## How does reactivity work in Wized? Wized constantly monitors the state of your application, including the value of variables, cookies, API responses, and other relevant data. Whenever a change occurs in any of this data, Wized automatically re-evaluates all conditions associated with your element configurations. If a condition changes, Wized instantly updates the appearance or behavior of the corresponding element, without the need to reload the page. ## JSON (JavaScript Object Notetion) JSON is a lightweight format for exchanging data between different systems. It plays a crucial role in interoperability, allowing Wized to communicate seamlessly with various APIs and services. At Wized, JSON is widely used to represent structured data, such as the results of API requests or information stored in the database. ## DOM (Document Object Model) The DOM is a tree-like representation of the structure of a web page. In Wized, you can use JavaScript to interact with the DOM, which is essential for creating engaging and dynamic user interfaces. This allows you to modify page elements, add or remove content, and respond to user events in real-time. ## Return In Wized, the return keyword is required for every action that needs to return a value. This value can be the result of a validation, the response from an API, or any other data necessary for the action to work correctly. Proper use of `return` is key to the flow logic of applications in Wized. For example, if you want to change the color of an element, you must use return followed by the color you want (in hexadecimal or text). ## Null In JavaScript, null represents the intentional absence of any value. In Wized, you can use null to indicate that a variable or property has no value assigned. ## Undefined In JavaScript, undefined indicates that a variable has been declared but no value has been assigned to it. In Wized, you might encounter undefined when accessing properties of objects that don't exist or when using variables that haven't been initialized. Handling undefined appropriately also helps to prevent errors during program execution. ## True and False `true` and `false` are the two boolean values in JavaScript, representing truth and falsity, respectively. In Wized, you can use these values in conditionals and other logical expressions to control the execution flow of your application. ::: tip Example **Example of using boolean values in a conditional statement:** ```javascript let userLoggedIn = true; if (userLoggedIn) { console.log('Welcome back!'); } else { console.log('Please log in.'); } ``` ::: ## If...else The `if...else` structure is a method to implement conditional statements in JavaScript. In Wized, you can use `if...else` to perform different actions depending on whether a condition is met or not. ## Logical Operators (&&, ||, !) Logical operators are used to combine or negate boolean expressions. In Wized, you can use `&&` (AND), `||` (OR), and `!` (NOT) to create more complex conditions and control the flow of your logic precisely. ::: tip Example **Example of using logical operators:** ```javascript let isAdmin = false; let isUser = true; if (isAdmin || isUser) { console.log('Access granted'); } else { console.log('Access denied'); } ``` ::: ## Ternary Operator (? : ) The ternary operator is a shorthand way of writing an `if...else` statement on a single line. In Wized, you can use the ternary operator to assign a value to a variable based on a condition. ::: tip Example **Example of using the ternary operator:** ```javascript let age = 18; let canVote = age >= 18 ? 'You can vote' : 'You cannot vote'; console.log(canVote); ``` ::: ## Wized attributes In your Webflow-powered website, you need to add custom HTML attributes with the `wized` key and the value you want (e.g., `wized="my_button"`). Esto permite a Wized reconocer y utilizar dicho elemento dentro del configurador. > **Note**: All elements on your website are visible in the Wized configurator, but only those with the `wized` attribute can be used to create features. ## Wized-cloak The `wized-cloak` attribute is used to hide UI elements until Wized has finished loading and rendering the page. This prevents users from seeing raw content or flashing elements while the application is initializing. ## Wized-loader The `wized-loader` attribute is used to display a loading indicator while Wized is processing an action or retrieving data from an API. This provides visual feedback to the user and improves the overall application experience. # Return In Wized, the `return` keyword is required for every action that needs to return a value. This value can be the result of a validation, the response from an API, or any other data you need for the action to work correctly. For example, if you want to change the color of an element, you must use return followed by the color you want (in hexadecimal or text). # Creating a New Branch Creating a new branch is essential when working on a new feature or fixing a bug. It helps keep your work organized and ensures the main branch remains stable. Follow the steps below to create a new branch. ## Steps to Create a Branch 1. **Open the branch dropdown menu** ![Main Options](./images/main-options.png) 2. **Select "Create new"** Click on the **"Create new"** option from the dropdown menu. ![Create Branch](./images/create.png) 3. **Name your branch** Provide a clear and descriptive name for your branch. Use names that reflect the purpose of the branch, such as `staging`, `feature/posts-rendering`, or `bugfix/login-issue`. 4. **Click "Create"** Confirm your action by clicking the **"Create"** button. Once created, your new branch will appear in the branch list and will automatically be set as the active branch. ## Best Practices for Naming Branches - Use lowercase letters and hyphens (`-`) to separate words (e.g., `feature/add-user-authentication`). - Include a prefix to indicate the type of work, such as `feature/`, `bugfix/`, or `hotfix/`. - Keep names concise but descriptive. > **Important:** > Branches can only be created from the default main branch. By following these steps and best practices, you can effectively manage your workflow and collaborate with your team. # Delete Branch Removing branches that are no longer needed helps keep your workspace organized and reduces clutter. ## How to Delete a Branch Follow these steps to delete a branch: 1. **Locate the branch**: Find the branch you want to delete in the branch list. ![Branch select](./images/branch-select.png) 2. **Select the branch**: Click on the branch name to ensure it is selected. 3. **Open the options menu**: Click the dropdown button next to the selected branch name. ![Options](./images/options.png) 4. **Select `Delete`**: Choose the `Delete` option from the dropdown menu. 5. **Confirm the deletion**: A confirmation popup will appear. Review the details and click `Confirm` to permanently delete the branch. > **Warning**: Deleting a branch is irreversible. Ensure the branch is no longer needed and all important changes have been merged or saved elsewhere before proceeding. # Branching Branching allows you to create, manage, and work with multiple versions of your project configuration. Use branches to experiment, develop features, or collaborate safely without affecting the main configuration. ## Use Cases - **Feature Development:** Work on new features in a separate branch without affecting the main or production configuration. This allows for safe experimentation and testing. - **Bug Fixes and Hotfixes:** Quickly patch issues by creating a branch from the current state, applying the fix, and merging it back when ready. - **Experimentation:** Try out new ideas, settings, or integrations in an isolated branch. If the experiment is successful, merge it; if not, simply delete the branch. - **Collaboration:** Multiple team members can work on different branches simultaneously, reducing conflicts and making it easier to review and integrate changes. - **Release Management:** Prepare and test release candidates in dedicated branches before merging them into the main branch for deployment. ### Tips for Managing Branches - **Keep branches organized**: Use clear and descriptive names for your branches to make it easier to identify their purpose. - **Regularly merge changes**: To avoid conflicts, merge changes from the main branch into your working branch frequently. - **Delete unused branches**: Once a branch is no longer needed, delete it to keep your repository clean and manageable. - **Test thoroughly**: Before merging a branch, ensure all changes are tested to avoid introducing bugs or breaking functionality. ## Learn to: - [Create a New Branch](./create.md) - [Rename a Branch](./rename.md) - [Switch Branches](./switch.md) - [Preview Branch Changes](./preview.md) - [Merge Branch Changes](./merge.md) - [Update Branch from Main](./update-from-main.md) - [Delete Branch](./delete.md) - [Revert Merged Changes](./revert.md) # Merge Branches Merging changes from one branch into the `main` branch allows you to publish updates and integrate new features or fixes into your primary codebase. This process ensures that the latest developments are consolidated and made available for deployment or further collaboration. ## Steps to Merge Branches 1. **Select the branch**: Ensure the branch you want to merge is selected. If it is not active, switch to it. 2. **Open branch options**: Click the dropdown button next to the branch name. 3. **Click the "Merge" button**. ![Branch options](./images/options.png) 4. **Review changes**: Compare and review the changes to ensure everything is correct. ![Branch merge](./images/merge-popup.png) 5. **Confirm the merge**: Click the `Merge` or `Merge and delete branch` option to finalize merging Once the merge is complete, the changes from the selected branch will be integrated into the `main` branch. The page will automatically reload to reflect the updates. # Preview Site Changes from a Branch Previewing changes from a specific branch allows you to test updates in the site before merging. Follow the steps below to preview your branch changes on the website: ## Steps to Preview Branch Changes 1. **Select the branch**: Ensure the branch you want to preview is selected. If it is not active, switch to it first. 2. **Click the "Publish" button**: Locate the "Publish" button in the top-right bar of the interface. Click it to open a popup menu. 3. **Select "Preview" option**: In the popup menu, choose the "Preview" option. This will generate a temporary preview link for the branch. ![Preview popup](./images/preview-popup.png) 4. **View the preview**: Use the provided link to view the website with the changes from the selected branch. By previewing branch changes, you can ensure everything looks and functions as expected before publishing. # Rename a Branch Follow the steps below to update the name of a branch. Renaming a branch can help keep your repository organized and make branch names more descriptive. ## Steps to Rename a Branch 1. **Select the branch**: Ensure the branch you want to rename is selected. If it is not active, switch to it first. 2. **Open branch options**: Click the dropdown button next to the branch name to access its options. ![Branch Options](./images/options.png) 3. **Choose "Rename branch"**: From the dropdown menu, select the "Rename branch" option. 4. **Update the branch name**: Enter the new name for the branch. ![Branch Options](./images/rename.png) 5. **Save changes**: Confirm and save the updated branch name. > **Note**: The name of the main branch cannot be changed. # Reverting Changes If you are unsatisfied with the changes after merging, you can revert the changes. After each merge to the `main` branch, a backup is automatically created for you. This backup contains the main configuration prior to the merge. To restore this backup, follow these instructions: ## Steps to Restore a Merge Backup 1. **Switch to the Main Branch** Ensure you are on the main branch to access the backups. 2. **Open the Settings Panel** Navigate to the settings panel in your application. 3. **Access the Backups Section** Locate the backups section within the settings panel. 4. **Restore or Preview the Auto-Created Backup** Choose to either restore or preview the automatically created backup. ![Auto backup](./images/auto-backup.png) # Switching Branches Easily switch between branches to manage different versions of your configuration. ## Steps to Switch Branches 1. **Open the Branches Selector popup.** ![Branch Selector](./images/branch-select.png) 2. **Select the branch you want to switch to.** 3. **The page will reload, allowing you to work on the selected branch.** # Updating Your Branch from Main Keep your branch up-to-date by incorporating the latest changes from the main branch. ## Steps to Update Your Branch 1. **Switch to Your Branch** Ensure the branch you are working on is active. If not, select it. 2. **Access Branch Options** Open the branch dropdown menu. ![Branch Options](./images/options.png) 3. **Click update** Click the "Update" button to start the process. 4. **Review Changes** Compare and review the changes before proceeding. ![Review Changes](./images/update-from-main.png) 5. **Confirm the Update** Finalize the update to merge changes from the main branch into your current branch. Once completed, your branch will include all updates from the main branch, ensuring you're working with the latest code. # Dashboard The Dashboard is the central hub where you can manage all your projects in Wized. Here, you’ll find an organized grid displaying every project you’ve created, making it easy to access and manage them. Each project card provides key information, including its **URL** and the **current plan type**, ensuring you have a clear overview of your projects at a glance. ## Managing your projects - **Project grid:** Each project is displayed in a structured grid, allowing for quick navigation. Clicking on a project will take you directly to its workspace. - **Settings access:** Each project card includes a **gear icon (⚙️)**, which opens the **workspace settings**. From here, you can: - Change the **workspace name**. - **Add collaborators** to work on the project. - **Delete the workspace**, if necessary. ## Collaborators Wized allows you to invite collaborators to your projects, enabling teamwork and efficient development. However, collaborators have **limited permissions** compared to the project owner. ### What can collaborators do? ✔ Access the project and contribute to its development. ✔ Modify logic, interactions, and API connections. ✔ Work alongside other team members in the same environment. ### What can’t collaborators do? ❌ Delete the project. ❌ Move the project to another workspace. ❌ Change the ownership of the project. ### Ownership and transfer - The **original creator** of a project is always its **owner**. - Owners can transfer a project to another workspace if needed. - There is no limit to the number of collaborators you can add to a project. With these features, the Dashboard gives you full control over your projects and team, making it easy to manage, collaborate, and organize your work efficiently. # Transferring projects Transferring a project is a crucial step, especially for freelancers delivering work to clients or teams moving projects between workspaces. In Wized, **only the project owner** has the ability to transfer a project to another workspace. ## How to transfer a project To ensure a smooth transfer, follow these simple steps: ### 1. Invite the recipient to the current workspace Before transferring the project, make sure the person receiving it has access to the destination workspace. To do this: - Go to your **current workspace settings** (⚙️). - Add the recipient as a **collaborator**. - Once invited, they will be able to see and access the project. ### 2. Move the project Once both the **current owner** and the **recipient** are collaborators in the same workspace: - Locate the project in your **dashboard**. - Click the **gear icon (⚙️)** on the project card. - Select **"move to workspace"**. - A list of available workspaces (both your own and those where you're a collaborator) will appear. - Choose the **destination workspace** and confirm the transfer. And that’s it! The project is now in the new workspace. ## Important considerations ### Active subscriptions must be canceled Before transferring a project, ensure that there is **no active subscription** associated with it. Subscriptions are linked to the **payment methods of the current owner**, so they must be canceled before the project can be moved. ### Ownership after transfer Once the project is transferred, it will belong to the new workspace. The original owner will no longer have control over it unless they are added back as a collaborator. # Cookies Cookies are small pieces of information stored in the user's browser, acting as long-term memory for your website. Unlike variables, cookies persist even after the user closes the page or browser, allowing you to retain important data over time. ## Why use cookies? - **Personalization:** Store user preferences such as language, or theme settings for a tailored experience. - **Authentication:** Maintain user sessions by storing authentication tokens, preventing the need to log in repeatedly. - **Tracking and analytics:** Track user behavior, visited pages, or viewed products to optimize the experience. - **Shopping carts and dynamic storage:** Temporarily store cart contents or other session data without losing selections when navigating. ## Creating and managing cookies ![cookie-section](cookie-section.png) In the **Data Store Panel**, you'll find the `Cookies` section, where you can: - **View existing cookies:** See a list of all created cookies and their current values. - **Create new cookies:** Click on the `+` icon. This will open the right panel, where you can set the new cookie. Once created, cookies can be accessed in the [function editor](/function-editor/), using `c.` [parameter](/function-editor/parameters). ::: info To modify or delete a cookie Go to the `data sotre` panel and choose a cookie, then in the right panel you can delete it or modify its current values. ::: ## Cookie settings options ![cookie-settings](cookie-settings.png) Once you choose a cookie, or create a new one, the right panel will open, where you can: - **Name:** Assign a descriptive name to identify the cookie. - **Lifetime:** Define how long the cookie remains in the user's browser: `1 day, 7 days, 30 days, 1 year` The cookie persists for the selected period. - **Delete:** Permanently deletes the selected cookie. ## Cookies and the function editor To access a cookie value in the [function editor](/function-editor/), use the parameter `c` followed by the cookie name. For example, if a cookie is named `preferredTheme`, you can retrieve its value with: `c.preferredTheme` ```js return c.preferredTheme; ``` ## Examples of using cookies in Wized ### **1. Toggle between light and dark mode using a cookie** In this example, a user can toggle between **light** and **dark** mode by clicking a button. This is achieved by: - Using a **cookie (`theme`)** to store the user's preferred theme. - Using an [element event](/elements/events) **(On Click)** on a button to update the `theme` [cookie value](/elements/events#set-cookie). - Using a **CSS Classes** [configuration](/elements/configuration-types/multi-use/set-class) on the `body` element to apply the `"dark"` class if `c.theme === "dark"`. #### Setup: 1. **Create the cookie: `theme`** - **Default value:** `"light"` - **Can be:** `"light"` or `"dark"` 2. **Button event:** Updates the cookie value when clicked. 3. **CSS Classes on `body`:** Adds `"dark"` class when the cookie value is `"dark"`. --- #### Updating the `theme` cookie with a button click - Add an **"On Click"** event to a toggle button. - Set the action to **"Set Cookie"**, updating `theme` to its opposite value. ```js return c.theme === 'light' ? 'dark' : 'light'; ``` --- #### Applying the dark mode class to `body` - Add a **CSS Classes** configuration to `body`. - Apply `"dark"` **only if** the `theme` cookie is `"dark"`. ```js return c.theme === 'dark' ? 'dark' : ''; ``` #### **How it works:** 1. When the page loads, the `theme` cookie is checked. 2. If the value is `"dark"`, the `"dark"` class is added to `body`, applying dark mode. 3. When the user clicks the toggle button: - The `theme` cookie updates to its opposite value. - Wized **reacts** to this change and updates the CSS class automatically. --- ### **2. Show or hide an element based on authentication status** In this example, the [visibility](/elements/configuration-types/single-use/set-visibility) of an element (e.g., a "Logout" button) is controlled based on whether the user is authenticated. Since cookies store string values, it is assumed that a token is stored in `auth`, and its presence is validated. #### **Setup:** 1. **Cookie: `auth`** - **Value:** Contains a session token when logged in (e.g., `"abc123xyz"`). - **Empty (`null` or `""`) if the user is not logged in**. 2. **Visibility configuration on the element:** - The element is shown only if `auth` contains a token. #### **Validating authentication status** - Add a [visibility](/elements/configuration-types/single-use/set-visibility) configuration to the "Logout" button. - The button is **visible only if** `auth` contains a valid token. ```js return c.auth && c.auth.length > 10; ``` #### **How It works:** 1. When the page loads, Wized checks the `auth` cookie. 2. If `auth` contains a session token (`length > 10`): - The **Logout button is shown**. 3. If `auth` is missing or too short: - The **Logout button is hidden**. 4. If the user logs out and the `auth` cookie is cleared: - Wized **detects the change** and hides the Logout button in real time. ::: info Note Cookies store data for a predefined **lifetime**. However, for long-term data storage, such as **user settings**, it is often better to store information in a **database** to ensure reliability and security. ::: # Forms **Forms in Wized** allow you to collect and process user input efficiently. They work by grouping multiple input fields into an [object](/function-editor/data-types#objects), making it easier to handle data and submit it through [requests](/requests/). ::: warning Note Make sure to read and understand the differences between using [inputs](/data-store/inputs) and **forms** before choosing one. Avoid using both for the same elements, as they behave differently. ::: ## How do forms work? Wized automatically **detects and structures** native Webflow forms without requiring complex setups. Here’s how: ### **1. Create a form in Webflow** - Add a **Webflow form element** to your page. - Include the necessary input fields (`text`, `email`, `password`, etc.). - Assign **a unique name** to each input field in Webflow’s settings. This name will be used in Wized. ![form-name-inputs](form-name-inputs.png) ::: info Note You can also use embedded custom elements ::: ### **2. Wized attribute** - **Do not add Wized attributes to individual inputs**. - Add the **Wized attribute** only to the `form` element. - Wized will automatically recognize the form and all its inputs. ![form-wized-attribute](form-wized-attribute.png) ### **3. How Wized structures form data** Once detected, the form will appear in the **data store** under the “Forms” section: - The **form itself** is converted into an **object**. - Each **input field** inside the form becomes a **property** of this object. - The **input names** set in Webflow are used as the **keys** of the object. ![form-overview-dataStore](form-overview-dataStore-panel.png) ::: info Note At first, the form values will be `empty` since Wized only fills them **after the form is submitted**. ::: --- ## Accessing form values Unlike [inputs](/data-store/inputs) (which update in real time), **form values are only available after submission**. To access a value from a submitted form, use: ```js return f.loginForm.email; // Retrieves the email input value ``` If the form hasn’t been submitted, this will return `empty`. --- ## Submitting a form and sending data via API To process and send form data via an API [request](/requests/), follow these steps: 1. Select the **form element** in Wized. 2. Add an **On Submit** [event](/elements/events). 3. Enable **Prevent Default** to stop Webflow’s default form submission. 4. Use a **perform request action** to send the form data. ### Example sending a login request: Imagine a login form where users enter their email and password. To send this data to an API, follow these steps: 1. Create a [Request](/requests/) in Wized (e.g., `login`). 2. In the **Body** section, add the required `key-value` pairs (e.g., `email`, `password`). 3. Set the values using the [Function Editor](/function-editor/): For `email`: ```js return f.loginForm.email; ``` For `password`: ```js return f.loginForm.password; ``` This ensures that the submitted form values are dynamically passed to the API request. --- ## Key takeaways ✔ **Wized automatically recognizes Webflow forms** (no need to manually create forms in Wized). ✔ **Form inputs are grouped into an object** for easy data handling. ✔ **Form values are only accessible after submission.** ✔ **Forms must have an "On Submit" event with "Prevent default"** to send data to an API instead of Webflow. --- ## **Inputs vs forms** When working with Wized, it is important to understand the difference between **forms** and [inputs](/data-store/inputs) to use them correctly and avoid common mistakes. ### Forms: Structured data collection Forms are used to group multiple input fields into a single structure, making data management easier. They are particularly useful when you need to collect structured information, such as login credentials or contact details. #### Key characteristics of forms - **Data grouping:** Forms bundle multiple input fields together, making it easier to send structured data. - **Accessibility:** Users can submit forms by pressing the `Enter` key. - **Native Webflow validations:** Forms support Webflow’s built-in validation, such as required fields, email formatting, and number restrictions. - **Delayed value access:** The values inside a form are **only accessible after submission**, not in real time. - **Recommended use:** Forms are best used when collecting structured user data that needs to be validated before submission. --- ### Inputs: Real-time value detection Inputs allow you to collect and process user input on an individual basis, making them useful when you need real-time value updates. Unlike forms, inputs do not require submission to access their values. #### Key characteristics of inputs - **Independent data handling:** Inputs work individually rather than as part of a structured form. - **No Enter key submission:** Unlike forms, pressing `Enter` does not trigger submission. - **Real-time value access:** Input values can be accessed and modified as the user types, enabling instant feedback. - **Recommended use:** Inputs are ideal when you need to process user input dynamically, such as formatting numbers, validating age restrictions, or enabling/disabling elements based on input values. #### Example use case A **currency input field** where a user enters a number, and it is automatically formatted as a currency value (`$1,234.56`) in real time. --- ### Choosing between inputs and forms | Feature | Forms | Inputs | | -------------------------- | ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | | **Data grouping** | Groups multiple inputs into a single structure | Each input is handled individually | | **Accessibility** | Can be submitted by pressing **Enter** | Cannot be submitted with **Enter**, requires a separate button | | **Validation** | Uses **Webflow’s native validations** (required fields, email format, numbers, etc.) | Requires **custom validation** via function editor | | **Real-time value access** | ❌ Values are only accessible **after form submission** | ✅ Values can be accessed **in real time** | | **Best use case** | Collecting **structured** user data that requires validation before submission (e.g., login, contact forms) | Running **real-time logic** based on user input (e.g., formatting numbers, validating age dynamically) | # Intro to the data store The **data store** is the central hub for monitoring and managing all real-time data within your Wized project. It provides a comprehensive overview of the state of your application, allowing you to track and interact with variables, cookies, URL parameters, API requests, and other critical data points. ## Why is the data store important? Building a dynamic web application requires managing data efficiently. The **data store** simplifies this by providing a **real time, centralized** view of all data elements that power your app’s functionality. With it, you can: - **Monitor the live state of your application** – Instantly see how variables, cookies, and other data points change as users interact with your site. - **Debug requests and logic efficiently** – Track API requests and responses, validate authentication tokens, and detect errors in data flow. - **Optimize app behavior** – Ensure that dynamic elements update correctly by checking their current values in real time. - **Simplify development** – Use the data store as a workspace to experiment with different data configurations before implementing them in your app. ## Navigating the data store You can access the data store from the **left sidebar** by clicking on `data store`. This opens a panel divided into two main sections: ### 1. General overview This section provides a **real time snapshot** of all key data elements, including: - **Variables** – All variables created within Wized, displayed with their current values. - **Navigation** – Information about the current page and navigation-related data. - **Cookies** – A complete list of cookies managed by your application, with their live values. - **Secrets** – Securely stored values that can be used for authentication or API calls. - **Input fields & forms** – Any input fields or forms detected on the current page (e.g., login forms, search bars), along with their current user-entered values. Each subsection displays data as a **list**, where you can instantly see the current value of each item. These values update in real time, making it easy to test and refine logic configurations without leaving the dashboard. Additionally, from this section, you can **create new variables, cookies, secrets, and parameters** directly, streamlining the setup of your application’s dynamic behavior. ### 2. Requests overview This section lists all **API requests** created in Wized. Each request is displayed with its **status and response details**, allowing you to track and debug external data interactions. Next to each request, you will find three action buttons: - **Play** – Manually trigger the request to test its execution. - **Preview** – Open and edit the request configuration in the right panel. - **Expand** – View real-time request details, including: - Whether the request has been executed (`hasRequested`). - If the request is currently running (`isRequesting`). - The HTTP status (`status` and `statusText`). - Whether the request was successful (`ok`). - The received data (`data`). - The headers of the response (`headers`). Before a request is executed, these properties will be `null` or `false`. Once triggered, they update in real time, allowing you to monitor its success and response data. ## How to use the data store effectively - **Debug your application:** - Check if variables, cookies, or parameters are updating as expected. - Verify requests responses and diagnose issues if a request is failing. - **Test real-time interactions:** - Modify variables and cookies on the fly to see how your app responds. - Ensure that navigation-based data updates correctly. - **Optimize API calls:** - Manually execute requests to test endpoints. - Validate API responses before integrating them into your app logic. ## Key takeaway The **data store** is an essential tool for developing and debugging your Wized project. It provides **live visibility** into all critical data points, helping you build a more robust, responsive, and error-free application. Make sure to explore the data store regularly while building your app—it’s the best way to **stay in control of your data** and **ensure everything works as expected**. # Inputs **Inputs in Wized** allow you to capture and use data entered by users in real time. Unlike [forms](/data-store/forms), inputs do not group data but provide immediate access to the values typed by the user. This makes them ideal for dynamic interactions, real-time logic execution, and live data formatting. ::: warning Note Make sure to read and understand the differences between using **inputs** and [forms](/data-store/forms) before choosing one. Avoid using both for the same elements, as they behave differently. ::: ## How do inputs work? When an input field in Webflow has the [Wized attribute](/start-here/getting-started/wized-attribute), it is automatically detected and listed in the **Data Store** under the `Inputs` section. Unlike forms, inputs are recognized individually. ### Key characteristics of inputs: - **Real-time data access:** The value of an input updates in real time as the user types. - **Independent behavior:** Each input is treated as a separate element, meaning it does not depend on a form submission. - **Event-driven logic:** Inputs can trigger actions based on user input. ## Where do inputs appear in Wized? Inputs are dynamically recognized based on the current page in the Wized configurator. If you are on the `/dashboard` page, only the inputs present on that page will be listed in the **Data Store**. ## How to use inputs in Wized? Inputs are primarily used to capture user data and integrate it into the logic of your Wized application. You can: ### **Use input values in logic** The input values can be used in the [Function Editor](/function-editor/) to dynamically update elements, validate data, or interact with API requests. **Example 1: Validate user age in real time** ```js return i.age >= 18; // Returns true if the user is 18 or older ``` **Example 2: Format currency input as the user types** ![input-example](input-example.png) ```js return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(i.price); ``` ### **Trigger events based on input changes** You can configure **On Change** or **On Input** events to execute logic when the user modifies an input field. **Example 3: Show a warning message when the input is empty** ```js return i.email.trim() === '' ? true : false; // Shows a warning if the email field is empty ``` ### **Send input data via API requests** To send input values in an API [request](/requests/), configure an [On Click](/elements/events) event on a button and use the [Function Editor](/function-editor/) to pass the input values. **Example 4: Sending input data in a request** 1. Ensure the `div button` has the **Wized attribute**. 2. Add an **On Click** event to the button. 3. Configure the request in Wized and map the inputs inside the Function Editor. Each key-value pair in the request body must be set individually: - **Key:** `email` → **Value:** `return i.login.email` - **Key:** `password` → **Value:** `return i.login.password` This structure ensures that input values are properly sent when the user clicks the submit button. ## When should you use inputs instead of forms? | Feature | Inputs | Forms | | -------------------------------------- | ------ | ------ | | **Real-time value updates** | ✅ Yes | ❌ No | | **Grouping multiple fields** | ❌ No | ✅ Yes | | **Trigger actions on every key press** | ✅ Yes | ❌ No | | **Submit using the Enter key** | ❌ No | ✅ Yes | | **Use Webflow native validations** | ❌ No | ✅ Yes | | **Best for data collection** | ❌ No | ✅ Yes | | **Best for interactive logic** | ✅ Yes | ❌ No | ## Best practices - **Use inputs** when you need to capture user input in real time for dynamic updates, live validation, or interactive logic. - **Use forms** when you need to collect structured data and submit it in one action. - **Avoid mixing both approaches** unless necessary for a specific use case. # Navigation The **navigation** section in the Data Store provides real-time information about the current state of the URL in your web application. This includes the full URL, any parameters present, and previously defined parameters with their current values. Understanding and utilizing **navigation data** is essential for controlling application logic dynamically. You can use these values to trigger API requests based on the active page, conditionally show or hide elements, or pass information between different pages. ## What information does navigation provide? The **navigation** section consists of three main data points: 1. **href** (`n.href`) - A **string** containing the full URL of the current page. - Updates automatically as you navigate between pages within your website. 2. **parameter** (`n.parameter`) - An **object** containing all URL parameters created. - Each parameter is stored as a key-value pair, where: - The **key** is the name of the parameter. - The **value** is the current assigned value or `null` if it is not set. 3. **parameter.`name`** (`n.parameter.`) - A **list of all previously defined parameters**, each displaying: - The **name** of the parameter. - Its **current value** (updates in real time). - If the parameter exists in the URL but is not defined in the Data Store, its value remains `null` until it is explicitly added. 4. **path** (`n.path`) - A string containing the path without the base URL. - Updates automatically as you navigate between pages within your website. ## How navigation works in real time The **navigation data** updates instantly as you browse your site within the Wized configurator. This means that: - If you **visit another page**, the `href` value updates automatically. - If a URL **contains parameters**, they are reflected immediately in `n.parameter`. - If you **manually add parameters** via the [Canvas](/wized-configurator/top-bar#🎨-canvas), they appear in real time in the Data Store. ::: tip Note - For a parameter to be visible in the Data Store, it must exist within Wized. - Even if a parameter is present in the URL, if it is not explicitly added, its value will be inaccessible. ::: ## How to use navigation data navigation data is a **powerful tool** for dynamic behavior in your application. Here are some common use cases: ### 1. Execute requests based on the active page You can use **navigation data** to control when a [request](/requests/) runs. For example, you can set up an [event](/global-events/) to execute a [request](/requests/) **only when the user is on any dashboard page**: ![navigation-example](navigation-example.png) ```js return n.path.includes('/dashboard'); ``` This ensures that the request will not trigger on other pages. ### 2. Show or hide elements based on URL parameters With Wized’s reactive system, elements can be conditionally displayed depending on navigation values. For example, you can [configure an element](/elements/configurations) to be visible only if a specific parameter is present, such as showing a discount banner only when the "promo" parameter exists: - Create a [visibility](/elements/configuration-types/single-use/set-visibility) configuration for the element you want to show or hide dynamically. Then, use the following code, replacing the parameter names as needed ```js return n.parameter.promo !== null; ``` Since Wized constantly listens for changes, the element will dynamically appear or disappear as the parameter changes. ### 3. Modify UI based on parameter values navigation parameters can be used in JavaScript functions to modify UI elements. For example, if a product page contains an id parameter, you can dynamically set the product name: - Create a [text](/elements/configuration-types/single-use/set-text) configuration for the element you want to modify. Then, use the following code, replacing the parameter names as needed ```js return n.parameter.id === '1' ? 'Product 1' : 'Other Product'; ``` This allows you to personalize content without needing separate pages for each product. ## Interacting with navigation in the function editor In the [function editor](/function-editor/), navigation values can be accessed using the n object. For example, to retrieve the current "id" parameter, you would use: ```js return n.parameter.id; ``` # Requests The **requests** section within the **data store** provides a centralized view of all API requests in your project. This section allows you to monitor, debug, and manually execute requests, giving you full control over their behavior and responses. ## Overview Each request is represented as a collapsible item in the list. The request name is displayed alongside three icons: 1. **Play icon:** Executes the request manually. 2. **Preview icon:** Opens the right panel to display request settings. 3. **Expand/collapse icon:** Reveals or hides the request’s response details. By expanding a request, you will see its **current properties and state**, making it easier to track execution, inspect returned data, and troubleshoot issues. --- ## Request properties Each request contains several key properties, dynamically updated upon execution. These are displayed in a structured format resembling a JavaScript object. | Property | Type | Default Value | Description | | ---------------- | ------- | ------------- | -------------------------------------------------------------------------------------------------- | | **hasRequested** | Boolean | `false` | Indicates if the request has been executed at least once. | | **isRequesting** | Boolean | `false` | Becomes `true` while the request is in progress. | | **statusText** | String | `null` | Displays the response status text (e.g., "Success", "Forbidden", "Not Found"). | | **status** | Number | `null` | The HTTP response code (e.g., `200`, `404`, `500`). | | **ok** | Boolean | `false` | `true` if the request was successful (`200-299` status range). | | **data** | Object | `null` | Stores the response payload, dynamically structured based on the returned data as Key-value pairs. | | **headers** | Object | `null` | Stores the response headers as key-value pairs. | ![request-overview](request-overview.png) When a request is executed, its **status, response data, and headers** update in real time. This provides a clear snapshot of the request’s success or failure, making it an essential tool for debugging. --- ## Using requests values Requests are not just for viewing responses they are **fully accessible** within the [function editor](/function-editor/), allowing dynamic data manipulation and logic execution. ### **Accessing request data** You can access request properties directly using the `r` parameter in the [function editor](/function-editor/). #### Get a user’s name from a request ```js return r.get_user.data.name; ``` #### Render a list of products ```js return r.products_request.data.products; // Assuming "products" is an array ``` #### Check if a request was successful ```js return r.login.ok ? 'Login successful' : 'Login failed'; ``` ### **Debugging requests** Since request states are visible in real time, you can: - **Identify errors** by checking the `statusText` and `status` properties. - **Verify successful execution** using the `ok` boolean. - **Inspect the returned payload** in the `data` object. # Secrets **Secrets in Wized** allow you to securely store `API keys` needed for [requests](/requests/). These secrets are encrypted and stored on our servers, ensuring that only the project owner can access them. When a request using a secret is executed, it is processed through our servers, where the actual API key is retrieved and applied securely. This prevents exposure of sensitive credentials on the client side. ### Why use secrets? - **Security:** By storing your API keys in secrets, you prevent them from being visible in your webapp source code, reducing the risk of leaks and unauthorized access. - **Requests via Wized server:** When you use a Secret in a [request](/requests/), the request is executed through our servers instead of directly from the user's browser. This adds an extra layer of security, especially for APIs that only accept requests from servers. - **Encryption:** Secrets are stored encrypted, ensuring that only you, as the project owner, can access their value. ### What kind of information should I store in secrets? - **API keys:** API keys are unique credentials that allow you to access external services, such as databases, third-party APIs, or payment platforms. Storing them in secrets is essential to protect them from potential leaks. ::: info Note Auth tokens are temporary credentials that allow users to access protected areas of your application after logging in. These tokens are typically stored in [cookies](/data-store/cookies). ::: ### Creating a secret 1. **Access the data store panel:** Click on the `Data Store` tab in the leftside bar. 2. **Secrets section:** You will find a list of the secrets you have previously created. 3. **Click the `+`:** Right panel will open, there you will be able to set the values of this secret. 4. **Fill in the fields:** - **Name:** Choose a descriptive name for your secret (for example, `api_key_stripe`). - **Value:** Enter the value of your API key. 5. **Save the secret:** Click the "Save" button to encrypt and store the secret securely. ### Using a secret To use a secret in a request, simply access its value in the Function Editor using the `s.` [parameter](/function-editor/parameters) followed by the secret name. For example: ```JavaScript // In the "Headers" configuration of a request: return s.my_secret_token ``` # Variables **Variables** in Wized act as dynamic containers that store data in real time, making them an essential part of your application's state. Wized variables are **reactive**, meaning that any change to their value automatically updates all elements, events, or configurations that depend on them. They can store various data types, including: - **Text** (strings) - **Numbers** - **Booleans** (`true` or `false`) - **Objects** - **Arrays (lists)** These variables allow you to create **logic-driven behaviors**, such as **showing or hiding elements**, **triggering events**, and **modifying element configurations** based on their current values. ::: warning Important Variable values reset to their initial state every time the page reloads or navigates to another page. To maintain values across pages, use cookies or enable the persist values option. ::: ## Managing variables in the data store The **Variables** section within the Data Store provides a clear overview of all created variables, including their **names, current values, and persistence settings**. Here’s what you can do: ![variables-section](variables-section.png) - **View existing variables:** See a real-time list of all stored variables and their values. - **Create new variables:** Click the "+" button to define a new variable. - **Modify variables:** Click a variable to edit its name or value. - **Delete variables:** Click the trash icon next to a variable to remove it. ## Configuring variables When creating or modifying a variable, you can define the following properties: ![variable-settings](variable-settings.png) ### **1. Name** Choose a clear, descriptive name. **Example:** If storing a username, name the variable `userName` instead of `var1`. ### **2. Initial value** Set the starting value using the **function editor**. You can use any data available in Wized, such as **cookies, API responses, or user inputs**. ### **3. Persistence options** Variables can persist across different scopes: - **None (Default):** The variable resets when the page reloads. - **Session Storage:** The variable persists as long as the browser tab is open. - **Local Storage:** The variable remains saved even after the browser is closed. ::: info Example If storing a shopping cart, **session storage** ensures it remains available while the tab is open, whereas **local storage** keeps it even after closing and reopening the browser. ::: ### **4. Computed variables** If enabled, the variable **automatically recalculates** whenever any of its dependencies (such as API data or user inputs) change. Useful for values that must update dynamically without manual intervention. --- ## Using variables in the function editor Once created, variables can be accessed and manipulated directly within the [function editor](/function-editor/). ### **Accessing a variable** To use a variable, prefix its name with `v.` **Example:** If you have a variable named `username`, retrieve its value using: ```js return v.username; ``` Practical Use Cases 1. **Displaying dynamic text** ```js return `Welcome, ${v.username}!`; ``` - **Calculate the total price of a shopping cart:** ```JavaScript // In the "Set Text" configuration of an item that displays the total price: let total = 0; for (const product of v.cart) { total += product.price * product.quantity; } return `Total: $${total.toFixed(2)}`; ``` - **Controlling the visibility of an element:** ```JavaScript // In the "Set Visibility" configuration of an element: return v.showElement; // Show the element if v.showElement is true, hide it if false ``` ## Variables and reactivity Variables in Wized are reactive, meaning that any change in their value will trigger an automatic update of events and configurations of elements that depend on them. This allows you to create dynamic and responsive user interfaces without the need to reload the page. - **Example:** Imagine you have a button that, when clicked, increments a counter stored in a variable called v.clickCount . You also have a text element that displays the value of this counter. 1. **Event:** On Click on the button 2. **Action:** Set Variable to increment the counter: v.contadorClics += 1; 3. **Configuration:** Set Text on the text element, with the return value `Clicks: ${v.contadorClics}` ; Every time the user clicks the button, the event will fire, the v.ClickCount variable will increment, and the element's text will automatically update to reflect the new value, all in real time! # Multi-use configurations Multi-use configurations allow you to apply multiple instances of the same configuration to a single element. These configurations give you the flexibility to manipulate various properties dynamically, enabling more complex and interactive behaviors. ## Why Use multi-use configurations? - **Greater flexibility:** Modify multiple aspects of an element without restrictions. - **Advanced customization:** Combine multiple configurations to achieve unique interactions. - **Data-Driven adaptability:** Dynamically adjust styles, attributes, or behaviors based on real-time data. ## How do multi-use configurations work? Unlike single-use configurations, which can only be applied once per element, multi-use configurations allow multiple instances on the same element. For example, you can add multiple **CSS classes**, **HTML attributes**, or **inline styles** to an element, each serving a different purpose. ## Common use cases - Applying multiple **CSS classes** dynamically based on user actions. - Assigning multiple **HTML attributes** for improved accessibility and behavior. - Using multiple **inline styles** to modify different visual aspects of an element in real time. - Setting multiple **URL parameters** dynamically for API calls or navigation. # CSS classes This configuration allows you to dynamically manage CSS classes for elements, enabling efficient control over their appearance and behavior based on specific conditions. ## How does It work? 1. **Select element:** Start by choosing an element in the elements panel in Wized where you want to apply the class configuration. 2. **Setting up** Go to the right panel and select the CSS classes configuration. 3. **Enter class name:** Input the exact name of the CSS class you want to add or remove from the element. 4. **Define the condition:** Use the [Function Editor](/function-editor/) to specify the condition that will determine whether the class is added or removed. This condition should return a boolean value (true or false). ::: warning Note - **The class must exist in Webflow:** Ensure that the CSS class you specify is defined in your Webflow project. Otherwise, you will not see visual changes when applying the class. ::: ## Advantages - **Style reuse:** You can define complex styles in Webflow and easily apply or remove them using Set Class. - **Organization and clarity:** By using CSS classes, you keep your code more organized and easier to understand, especially in large projects with many elements and styles. - **Flexibility:** You can combine Set Class with other settings and configurations to create dynamic and customized interactions, such as animations, appearance changes, or hover effects. This allows you to create more engaging and unique user experiences. ## Practical example For example, you have a button that you want to highlight only if the user is logged in. You can achieve this like this: 1. **In Webflow, create a CSS class named 'highlight':** Add the styles you want to apply to the button (for example, a different background color). 2. **In Wized, select the button and apply the set class setting.** 3. **In the "Class name" field, type "highlight."** 4. **In the Function Editor, type the following condition:** # Set HTML attribute The **Set HTML attribute** configuration enables you to modify the value of any HTML attribute of an element. ## How It works 1. **Select element:** Start by choosing the element in the element panel to which you wish to apply this configuration. 2. **Setting up:** Navigate to the right panel, in the properties section select the **Set HTML attribute** configuration. 3. **Specify the attribute key:** Input the name of the HTML attribute you intend to modify (for example, `src`, `href`, etc.). 4. **Define the value:** Use the `Function Editor` to specify the new value for the attribute. You can incorporate any data available in Wized, such as variables, cookies, request responses, or any other value. 5. **Add conditions (optional):** If desired, you can include a condition in the `Function Editor` to modify the attribute only under specific circumstances. ## Examples - **Change a product image:** - **Attribute:** `src` - **value:** ```javascript return r.getProduct.data.imageUrl; // Retrieves the image URL from the API response ``` - **Update a Button link:** - **Attribute:** `href` - **value:** ```javascript return v.destinationPage; // Provides the URL stored in a variable ``` - **Enable or disable an input:** - **Attribute:** `disabled` - **value:** ```javascript return !v.formularioValido; // Disables the input if the form is invalid ``` # Inline style The **inline style** configuration allows you to dynamically modify any CSS property of a selected element. This enables real-time visual adjustments based on user interactions, data changes, or other conditions within your application. ## Why use inline style? - **Dynamic styling:** Adjust the appearance of elements based on real-time data from variables, cookies, API responses, or other sources. - **Flexible customization:** Modify colors, sizes, visibility, and more without predefined styles. - **Reactive updates:** Since Wized is reactive, any change in the data source will automatically update the element's styles. ## How does It work? 1. **Select the element:** In Wized, in the elements panel click on the element you want to style. Make sure that the element has the [Wized attribute](/start-here/getting-started/wized-attribute). 2. **Setting up** In the right panel, select the **Inline style** configuration. 3. **Choose the CSS property:** Use the dropdown menu to select the CSS property you want to modify (e.g., `background`, `color`, `width`, etc.).To activate the dropdown, you must type the name of the property and Wized will show you a few suggestions 4. **Set the value:** Use the [Function Editor](/function-editor/) to specify the new value dynamically. The value can be derived from variables, cookies, API responses, or conditional logic. **Example:** ```js /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ return '#ff0000'; // for background color return '10px'; // for size return 'flex'; // for display ``` 5. **Multiple styles:** You can use this configuration multiple times on the same element, allowing you to modify several CSS properties simultaneously. 6. **Conditional styling (optional):** Add conditional logic within the Function Editor to apply styles only under specific conditions. **Example:** Assuming you want to change the `background` color of an element using [Ternary operators](/function-editor/basic-concepts#ternary-operators) ```js return r.request_name.status !== 200 && r.request_name.hasRequested ? 'red' : 'black'; ``` ## Creating smooth transitions By default, styles are applied instantly. However, you can create smooth transitions by combining **Inline style** with Webflow's built-in CSS transitions. ### Steps to apply transitions: 1. **Set Up CSS transitions in Webflow:** - Select the element and go to the "Effects" tab. - Under "transitions," click the "+" button. - Choose the CSS property you want to animate (e.g., `background-color`, `opacity`). - Set the duration and easing (e.g., `ease-in-out`). - If you want all properties to transition, select "All Properties." 2. **Apply inline style in Wized:** - Choose the same CSS property in the **inline style** setting. - In the Function Editor, write the logic to update the property based on your conditions. ```js //Change a button's background color when a request completes. return r.request_name.hasRequested ? 'blue' : 'red'; ``` ## Webflow interactions vs. Wized inline style Webflow’s built-in interactions allow for animations like hover effects, click-based visibility toggles, and scroll-triggered animations. Wized’s **inline style** expands these capabilities by providing **dynamic, data-driven styling**. ### When to use Wized instead of Webflow? Use Wized when: - **You need conditional logic** (e.g., change styles based on a user's role or API response). - **You want to connect styles to external data**, such as real-time product availability or API-driven updates. - **You require flexibility** beyond Webflow’s predefined interaction triggers. ## Practical examples ### 1. Change the background color of a button **CSS Property:** `background` ```js return 'red'; ``` ### 2. Display a progress bar based on request data **CSS Property:** `width` ```js return `${r.request_name.data.progress}%`; ``` ### 3. Change text color based on user role **CSS Property:** `color` ```js return r.getUserData.data.role === 'admin' ? 'gold' : 'black'; ``` ### 4. Hide an element if no data is available **CSS Property:** `display` ```js return r.getData.data.length > 0 ? 'block' : 'none'; ``` ### 5. Adjust font size dynamically **CSS Property:** `font-size` ```js return r.getSettings.data.isLargeText ? '20px' : '14px'; ``` # Add parameter to link The **Add parameter to link** configuration allows you to add additional information to links on your website. This information is appended to the end of the URL in the form of **query parameters**, which are key-value pairs separated by question marks `?` and ampersands `&&`. For example, if you have a link to a product page with the URL , you can add a query parameter called `id` with the value `12345` to indicate which specific product should be displayed: . ## How does it work? 1. **URL destination:** In Webflow, set the url or destination page to which you want the user to be redirected once clicked. ![button-webflow-settings](button-webflow-settings.png) 2. **Select the element:** Choose the element from the elements panel in Wized. Ensure that the element has a configured destination URL and has the [Wized attribute](/start-here/getting-started/wized-attribute) 3. **Setting up:** In the `settings` tab of the right panel, select the add parameter to link configuration. 4. **Choose the parameter:** Use the dropdown menu to select the parameter you want to add to the link. Make sure you have created the parameter in the data store first, or you can create it by clicking on the `+` icon. ![parameter-example](parameter-example.png) 5. **Define the value in the function editor:** In the [function editor](/function-editor/) specify the value you want to assign to the parameter. You can use any available data, such as variables, cookies, API responses, or even the value of other inputs. When you click the element, the parameter and its value will be automatically added to the destination URL. On the destination page, you can access this value using `n.parameters.parameter_name` in the function editor. ::: tip Note You can add as many parameters as you want. For each parameter, click on `add parameter`, and Wized will automatically append all set parameters to the destination URL. ::: ## Why use add parameter to link? - **Dynamic detail pages:** Pass the ID of a product, item, or other to load specific information about that product on the destination page. - **Filters and searches:** Pass search criteria or filters through parameters to display relevant results on the next page. - **Campaign tracking:** Add UTM parameters to your links to analyze traffic and performance of your marketing campaigns. - **Personalization:** Pass user information or preferences to personalize the content or functionality of the destination page. ## Example Imagine you have a list of products on your website and want to redirect the user to a details page with specific information about that product when they click on it. You can achieve this as follows: 1. **In Webflow, create a link element in the product card that points to the details page.** 2. **Apply the Add parameter to link setting.** 3. **Select the parameter `productId`** (make sure you have created it previously in the Data store panel). 4. **In the function editor, write:** ```javascript // Get the product ID from the rendered list return r.getProducts.data[v.i].id; // 'v.i' must correspond to the index of the product being clicked ``` ```javascript // Get the product ID return r.getProduct.data.id; ``` Now, when clicking on a product, the destination URL will include the `productId` parameter with the corresponding ID, allowing you to display the correct information on the details page. # Single-use configurations Single-use configurations are settings that can only be applied once per element. These configurations directly control an element’s content, structure, or visibility, making them essential for managing core interactions and display logic. ## Why are these configurations single use? - **Element-Specific control:** Some settings directly modify an element’s primary function (e.g., text content, visibility). - **Avoiding conflicts:** Allowing multiple instances of these settings on the same element could create inconsistencies or unpredictable behavior. - **Performance optimization:** Restricting these configurations ensures optimal rendering and updates. ## How do single use configurations work? Each element can have only one instance of a **single-use configuration**. For example, an element can have only one **text** setting, since defining multiple text sources would create conflicts. ## Common use cases - Setting dynamic **text content** based on request responses. - Controlling **visibility** based on conditions. - Rendering lists dynamically using **render list**. - Pre-filling input fields using **form value** or **input value**. # Render List The **Render List** configuration allows you to dynamically generate lists of elements based on **real-time data**. Whether pulling information from variables, cookies, request responses, or other sources, Wized ensures that elements are **duplicated and displayed** according to the number of items in your data set. ::: info Note **Render List does not automatically update the content of each item** it only duplicates the selected element. To make each duplicated item display unique data, additional configurations like `Text, Visibility` must be applied to each child element inside the selected element. ::: ## How It works ### 1. Design the `template element` Before using Render List, you must define a **template element** in Webflow, which will be the base structure for each item in the list. This element can contain text, images, buttons, and other UI components. ::: info Note Be sure to add the [Wized attribute](/start-here/getting-started/wized-attribute) to the `template element`. Additionally, add the `Wized attribute` to any child elements you want to have dynamic behavior. ::: ![render-template-ement](render-template-ement.png) --- ### 2. Set render list to the element Once the template element is ready: - **Select the element in Wized's elements panel.** - **Define an index variable** : (e.g., `v.i`) is required. This variable allows child elements to reference specific data for each item in the list. - **List value**: Provide an array (list) of data that determines how many copies of the template should be rendered. ::: warning Important If there are several rendering lists on the same page, each must have a **different** index variable to avoid conflicts. ::: --- ### 3. Setting up child elements Once you select the list you want to render and the index variable, the template element will be duplicated according to the number of items in the list. Each duplicated element will initially be an exact copy of the original, including text, images, and other content. ![template-elemenst-overview](template-elemenst-overview.png) To display dynamic information for each element, you need to set configurations each child element to render dynamic data. Follow this steps to personalize each list item: **Ensure child elements have the Wized attribute** - Every child element that should display dynamic data must have a [Wized attribute](/start-here/getting-started/wized-attribute) **Verify hierarchy** - Child elements must be **direct descendants** of the template element in Webflow. **Select the child element in Wized** - Open the **elements panel** and select the desired child element. **Apply configurations (Text, Visibility, Style, etc.)** - Use Wized configurations like **Set Text, Set Visibility, or Set Style** to make elements dynamic. **Use the index variable in function editor** - This variable ensures that each duplicated element **references the correct data**. --- #### Examples: - **Text :** To each text element such as titles, descriptions, etc. You must apply a [text](/elements/configuration-types/single-use/set-text) confituration to render text dynamically for each element. ![child-text-example](child-text-example2.png) You can use the [dot notation](/function-editor/basic-concepts#dot-notation) to access the desired path, or you can also click on the name of the property you want to use in the [data store](/data-store/) window, clicking on it will autocomplete the path inside the function editor, just replace the index `[0]` by the name of the chosen variable. **Example** ```js return r.get_all_products.data.products[v.index].name; // Assuming that `index` is the name of the variable that was selected as the index variable ``` ::: info Note Make sure you are using the `index variable` in the path you are using in the function editor, this will iterate over the list and each element will have its own information. ::: --- - **Images:** To render images dynamically, you must add an [HTML attribute](/elements/configuration-types/multi-use/set-html-attribute) to the image element where the `key` will be `SRC` and the value will be the `URL` of the image, make sure the URL ends in `.png`, `.jpg`, etc. ![image-renderlist-example](image-renderlist-example.png) You can use the [dot notation](/function-editor/basic-concepts#dot-notation) to access the desired path, or you can also click on the name of the property you want to use in the [data store](/data-store/) window, clicking on it will autocomplete the path inside the function editor, just replace the index `[0]` by the name of the chosen variable. **Example** ```js return return r.get_all_products.data.products[v.index].main_image_url; // Assuming that `index` is the name of the variable that was selected as the index variable ``` ::: info Note Make sure you are using the `index variable` in the path you are using in the function editor, this will iterate over the list and each element will have its own information. ::: ## Structuring and styling lists Wized **handles duplication** of list items, but **layout and styling** depend on how the container is structured in Webflow. To ensure proper rendering: - Use **flexible container layouts** that adapt to different amounts of content. - Apply **CSS grid or flexbox** for better responsiveness. - Keep the **template element simple** to avoid unnecessary complexity in duplication. --- ## The importance of the index variable The **index variable** (e.g., `v.index`) allows Wized to iterate over the data and assign a **unique** value to each duplicated item. | Item in List | Index Value (`v.i`) | | ------------ | ------------------- | | First Item | `0` | | Second Item | `1` | | Third Item | `2` | | ... | ... | Using `v.index`, child elements inside the list can reference **different** data points. ```javascript // Example: Only show "Add to Cart" button when stock is available return r.getProducts.data[v.index].stock > 0; ``` ::: info Note If `v.index` is not used, **all** items will display the same data, preventing dynamic behavior. ::: --- ## Rendering lists inside lists Wized supports **nested lists**, allowing you to display **lists within lists** (e.g., categories and subcategories). ### How to render nested lists: **1. Apply render list to the parent element** - Example: A list of product categories (uses `v.i` for indexing). **2. Apply render list to a child element inside the parent** - Example: A list of products within each category (uses `v.j` for indexing). ::: warning Note You should not use the same index variable for different lists rendered on the same page. ::: **3. Ensure different index variables for Each Level** - `v.i` for the parent list (categories). - `v.j` for the nested list (products inside categories). ```javascript // Example: Accessing nested product data return r.getProducts.data[v.i].categories[v.j].name; ``` ### Example structure ``` [Main List] -> Categories ├── [Item 1] -> "Electronics" │ ├── [Sub Item 1] -> "Laptop" │ └── [Sub Item 2] -> "Smartphone" ├── [Item 2] -> "Clothing" │ ├── [Sub Item 1] -> "T-shirt" │ ├── [Sub Item 2] -> "Jeans" ``` --- ## Practical examples ### Display product name in each list item ```javascript return r.getProducts.data[v.i].name; ``` ### Show "Add to cart" button only when stock is available ```javascript return r.getProducts.data[v.i].stock > 0; ``` ### Show index number for each item ```javascript return v.i + 1; // Displays item number starting from 1 instead of 0 ``` # Form values The **Form Values** configuration allows you to automatically populate form fields with predefined values. This is useful for improving user experience by pre-filling forms with existing data, dynamically updating fields based on user actions, or ensuring consistency in form submissions. ## How does It work? The **form values** configuration assigns values to multiple input fields within a form using the [function editor](/function-editor/). It allows you to retrieve and inject data from various sources, such as: - **Variables** (e.g., stored user preferences) - **Cookies** (e.g., authentication tokens) - **URL parameters** (e.g., tracking campaign data) - **API responses** (e.g., retrieving user profile data) - **Other inputs** (e.g., filling a field based on another input's value) ## How to use it? ### 1. Select the target form Ensure your form is properly set up in Webflow and contains the fields you want to populate. The form must have the [wized attribute](/start-here/getting-started/wized-attribute) to work correctly with this configuration. ![form-wized-attribute-example](form-wized-attribute-example.png) Once you have set up the form in Webflow, go to the elements panel in Wized and click the form element ### 2. Setting up - In the right panel, on the **settings** tab, go to the **form values** section. ![configuration-form-value](configuration-form-value.png) - Open the [Function Editor](/function-editor/) to define the values. ### 3. Define values in the function editor Write a JavaScript function that returns an object where: - **Keys** correspond to the exact names of the input fields. - **Values** contain the data to populate the fields. **Example:** ![form-values-example](form-values-example.png) ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ return { name: 'nelson', email: 'test@test.com', age: r.getUser.data.age || '', }; ``` ### 4. Enable "merge" (optional) The Merge checkbox controls whether to retain existing form values: - **Enabled:** Keeps existing values and updates only the specified fields. - **Disabled:** Replaces all form values with the ones defined in the function. Any field not included will be cleared. --- ## Considerations When using **form values**, keep in mind the following behaviors to ensure correct functionality: - **Matching field names:** The input field names in Webflow must exactly match the `keys` in the object returned by the function. If there is a mismatch, the corresponding fields will remain empty. In this example, we create a new input called `new_input` in Webflow. ![webflow-name-inputForm](webflow-name-inputForm.png) *** For an input called `new_input` this is what the function should look like in Wized ![form-input-name-example](form-input-name-example.png) ```javascript return { new_input: 'Hello there!', }; ``` - **Data type compatibility:** Ensure that the values you assign match the expected data types of the inputs. For example, if an input field is of type `number`, providing a string will result in an empty field. - **Data store visibility:** In the [Data store](/data-store/) panel, you can view the values assigned to the form through **form values** configuration. However, if a user manually modifies an input field, these changes will not be reflected in the [Data store](/data-store/) or accessible via Wized until the form is submitted. - **Reactive behavior:** Since Wized is reactive, if the data source used to populate the form is not available at the time of execution, the inputs will remain empty. However, as soon as the data becomes available, Wized will automatically update and fill the fields. ## Use cases - **Pre-filling user information:** Auto-fill forms with user details from an API response. - **Persistent form data:** Restore previously entered values using cookies or local storage. - **Dynamic form updates:** Adjust form fields based on user interactions (e.g., auto-filling a shipping address after selecting a user profile). - **Tracking and customization:** Populate forms with campaign data from URL parameters. **Example:** Auto-Fill Form with User Data Imagine a registration form where we want to pre-fill the user's name and email with data from an API response: ```javascript return { name: r.getUserProfile.data.fullName, email: r.getUserProfile.data.email, }; // With this setup, as soon as the data request completes, the form will automatically populate the fields. ``` # Input value The **input value** configuration allows you to dynamically pre-fill a specific input field within your form. Unlike [form values](/elements/configuration-types/single-use/set-form-values), which enables setting multiple inputs at once, **input value** focuses on a single field, providing more granular control. ## How does It work? 1. **Select the input field:** Ensure the input field you want to populate has the [wized attribute](/start-here/getting-started/wized-attribute) so that Wized can recognize and manipulate it. 2. **Apply the input value:** In Wized, Navigate to the **settings** tab in the right panel and select the **input value** configuration. 3. **Define the value in the function editor:** Use the Function Editor to return the specific value that should populate the input. The value can come from various sources such as variables, cookies, URL parameters, API responses, or other dynamic data. ```javascript return r.get_user.data.name || ''; ``` 4. **Real time updates:** If the user manually changes the value of the input, the new value will be reflected in the [Data Store](/data-store/) in real-time, allowing you to track changes dynamically. ## Considerations - **Wized attribute required** The input field must have the `wized attribute` to be recognized and updated by Wized. - **Data type compatibility** The assigned value must match the expected data type of the input field (e.g., a number input must receive a numerical value). - **User modified values:** Unlike Form Values, user-modified input values are accessible in real-time. If a user manually updates the field, the new value will be reflected in the Data Store and can be used dynamically within Wized. - **Reactive behavior** If the assigned value is not available at the time of execution, the input will remain empty. However, once the data source becomes available, Wized will automatically update the input field. ## Use cases - **Pre-filling forms:** If you have user information stored in cookies or variables, or your DB, you can use "Input Value" to pre-fill form fields. - **Displaying search results:** When performing a search, this function can be used to show the search terms within an input field. This allows you to edit or refine your queries. - **Updating input fields based on other values:** You can use conditional logic in the Function Editor to update the value of an input based on other data from your application. # Text configuration The **text** configuration in Wized allows you to dynamically display text based on the data available in your application. This includes variables, cookies, URL parameters, request responses, and more. You can formatting any text string using [formulas](/formulas/text) You can also set **validations and conditions** to create **customized text outputs** based on different scenarios. ## What is dynamic text? Dynamic text means that instead of writing **static** text (like `"Hello World"`), your text can **change automatically** based on real-time data. For example: - If you want to greet a user by name, you can use: ```js return 'Hello ' + r.userRequest.data.name; //This will display `Hello John` if the request response data returns `John` as the name. ``` - If you want to show a different message based on the current page: ```js return n.path === '/dashboard' ? 'Welcome to your dashboard' : 'Welcome to the site'; ``` ## Key benefits - **Fully dynamic:** Use real-time data to personalize text. - **Flexible logic:** Apply conditions, format data, and combine multiple sources. - **Seamless integration:** Works with request responses, variables, cookies, and more. ## How it works ::: info Note - The **text** configuration can only be applied to text elements. - The value of the text is set using the [**function editor**](/function-editor/), where you can write JavaScript expressions to define how the text should be displayed. ::: ### 1. Select the element In the Wized elements panel, click on the element where you want to set dynamic text. ![elements_overview](elements_overview.png) ### 2. Choose the text type In the right panel, go to the `text` section and select the type of content you want to display: - **Plain text** → Basic text (recommended for most cases). - **HTML** → If you need rich formatting. - **Markdown** → For formatted text like titles, lists, etc. ![text-type](text-type.png) ::: warning Note When using HTML or Markdown, ensure that the text does not contain untrusted content. If displaying data from external sources, sanitize it to prevent security risks like XSS attacks. ::: ### 3. Define the content Use the [function editor](/function-editor/) to write the JavaScript expression that will determine the text content. ![text-configuration-example](text-configuration-example.png) --- ## Writing expressions in the function editor The [**function editor**](/function-editor/) allows you to write JavaScript [formulas](/formulas/text) to define what text will be displayed. Here are some useful examples: ### Using request response data ```js return 'Your balance is: $ ' + r.request_name.data.balance; //Displays a user's balance dynamically. ``` --- ### Formatting request response data If your request returns a **timestamp**, you can format it into a human-readable date: ```js return new Date(r.request_name.data.timestamp).toLocaleDateString(); //Converts `"1672531200000"` into `"1/1/2023"`. ``` --- ### Combining multiple data sources ```js return ( 'Hello ' + (v.userName || r.userDetails.data.name) + '! Your role is: ' + (v.userRole || 'Guest') ); //Prioritizes the `userName` variable but falls back to an request response if not set. ``` --- ### Formatting numbers (e.g., Prices) ```js return `${r.request_name.data.price.toFixed(2)}`; //Ensures the price always has two decimal places. ``` --- ### Conditional text based on user input ```js return i.userAge >= 18 ? 'You can proceed' : 'You must be 18+'; //Changes the message based on the user’s age. ``` --- ## Common errors & how to fix them **Error: Accessing data it is not available** ```js return 'Hello ' + r.userRequest.data.name; // Might cause an error if the data hasn't loaded yet ``` **Solution: Use a fallback value** ```js return 'Hello ' + (r.userRequest.data.name || 'Guest'); ``` --- **Error: Forgetting to return a value** ```js 'Hello ' + r.userRequest.data.name; // This won't work ``` **Solution: Always use `return`** ```js return 'Hello ' + r.userRequest.data.name; ``` --- **Error: Overcomplicating conditions** ```js if (n.path === '/home') { return 'Welcome!'; } else { return 'You are not on the homepage'; } ``` **Solution:** Use the ternary operator `(? :)` for simpler conditional expressions. ```js return n.path === '/home' ? 'Welcome!' : 'You are not on the homepage'; ``` # Visibility configuration The **visibility** configuration in Wized allows you to dynamically **show or remove elements from the DOM** based on real-time data. Unlike [CSS properties](/elements/configuration-types/multi-use/set-style) like `display: none`, this configuration **removes the element from the DOM entirely** until the specified condition is met. This feature enables highly flexible and reactive user interfaces, adapting instantly to changes in **requests, variables, cookies, URL parameters, inputs**, and more. ::: info Note For this configuration to work, the element must be present in the DOM by default. If it has `display: none` in Webflow, Wized won't be able to apply the configuration. ::: ## How does It work? When you apply **visibility** to an element, Wized evaluates the **condition** that you written in the [function editor](/function-editor/). If the condition returns `true`, the element appears in the DOM. If it returns `false`, the element is completely removed. ![visibility-example](visibility-example.png) ### Key features: - **Fully dynamic** → Elements appear and disappear based on real-time data. - **DOM removal** → Unlike `display: none`, the element is not just hidden it is completely removed from the DOM. - **reactivity** → Wized continuously monitors changes in requests, variables, inputs, and other data sources to update visibility instantly. --- ## How to set up visibility ### 1. Select the Element In the **Elements Panel**, click on the element you want to show or hide dynamically. ![elements_overview](elements_overview.png) --- ### 2. Apply the visibility configuration In the **right panel**, locate the `visibility` section and open the **function editor** to define your condition. ![visibility-setting](visibility-setting.png) --- ### 3. Define a condition Write a [condition](/formulas/conditionals) that determines when the element should be visible. For example, to show an error message only if the login request failed: ```js return r.loginRequest.status !== 200 && r.loginRequest.hasRequested; ``` --- ## Practical use cases Here are some common scenarios where **visibility** is useful: ### Show an admin only button **Use case:** Show an **"edit content"** button only for administrators. ```js return r.getUserData.data.role === 'admin'; ``` --- ### Show a loading spinner until data is ready **Use case:** Display a **loading spinner** while an API [request](/requests/) is in progress. ```js return r.productRequest.isRequesting; // Hide the spinner once data is loaded. ``` --- ### Show an error message if a form submission fails **Use case:** Display an **error message** only if a form submission fails. ```js return r.formSubmission.status !== 200 && r.formSubmission.hasRequested; ``` --- ## Common mistakes & how to fix them ### **Error: The element doesn’t appear even when the condition is true** - **Problem:** The data source (e.g., request, variable) may not be available when the condition is first evaluated. - **Solution:** Ensure the request or variable is initialized before checking visibility. --- ### **Error: Using `display: none` instead of the visibility configuration** - **Problem:** Some users may mistakenly apply `display: none` in CSS, thinking it works the same way. - **Solution:** **visibility configuration removes elements from the DOM**, while CSS only hides them. --- ### **Error: Condition does not return a boolean** - **Problem:** Wized expects the condition to return `true` or `false`, but sometimes users forget to return a value. - **Solution:** Ensure your condition evaluates to a boolean. --- ## Why removing an element from the DOM? Unlike simply changing an element’s CSS `display` property, Wized’s **visibility configuration** completely **removes the element from the DOM**. This behavior offers several advantages and considerations: ### Benefits of removing an element from the DOM 1. **Performance optimization:** - Elements removed from the DOM are not processed by the browser, reducing memory usage and improving page performance. - This is especially useful when dealing with large lists, complex UI components, or elements that should only be present under specific conditions. 2. **Security & data protection:** - Sensitive content (such as admin-only sections) is completely removed from the page’s structure, making it harder to access via browser inspection or JavaScript manipulations. 3. **Accurate event & state management:** - Elements that do not exist in the DOM cannot trigger JavaScript event listeners, reducing unnecessary event bindings and preventing unwanted interactions. ### When Not to use visibility configuration While removing elements from the DOM is beneficial in many cases, there are scenarios where modifying [inline styles](/elements/configuration-types/multi-use/set-style) (e.g., setting `display: none`) is more appropriate: - **When animations/transitions are needed:** If you want an element to smoothly appear/disappear (e.g., with a fade-in effect), modifying `opacity` or `display` via inline styles allows for smooth CSS animations. - **When the element should retain state:** If hiding an element should not reset its internal state (e.g., form inputs retaining user data when toggled), using `display: none` is preferable. - **For elements frequently toggled:** If visibility needs to change rapidly (such as dropdown menus, tooltips, or modal windows), keeping the element in the DOM and toggling styles is more efficient than constantly adding/removing it. ### Choosing between `visibility` and `Inline Styles` | Feature | visibility Configuration (Removes from DOM) | Inline Styles (`display: none`) | | ------------------- | ------------------------------------------- | ---------------------------------- | | **Performance** | ✅ Better for heavy UI elements | ❌ Still loaded in the DOM | | **Security** | ✅ Hides sensitive data completely | ❌ Can be revealed via DevTools | | **State Retention** | ❌ Resets internal states | ✅ Preserves state when hidden | | **Animations** | ❌ Not possible without reloading | ✅ Allows smooth transitions | | **Use Case** | Best for **conditional UI logic** | Best for **temporary UI toggling** | # Intro to the element configurations The **Element Configuration** in Wized allows you to define the dynamic behavior of elements according to different scenarios that you define. These configurations offer a high degree of customization, allowing elements to react flexibly to data and user interaction. ## What are configurations for? Configurations allow you to modify the way an element behaves or renders in the interface. Some examples of what you can achieve, among others are: - **Render dynamic text** → Display dynamic text based on data obtained from an API, a variable, or a custom condition. - **Show or hide elements** → Control the visibility of an element based on a condition. - **Render dynamic lists** → Duplicate an element as many times as there are elements in an array. ## Setting up a configuration ### 1. Select the element In the Wized elements panel, click on the element. ![elements_overview](elements_overview.png) ### 2. Go to specific configuration section In the right pane, find the desired configuration ![configurations-overview](configurations-overview.png) - **Single use:** Configurations located in the upper rectangle are configurations that can only be applied once per element. This limitation helps prevent value overwriting, thereby reducing the risk of potential failures or inconsistencies in your application. [More info](/elements/configuration-types/single-use/) - **Multi use:** can be applied repeatedly to an element without risk of interference. This feature allows adding as many values as necessary. [More info](/elements/configuration-types/multi-use/) ### 3. Set te value Based on the configuration you selected, set the desired value or condition to make the element behave dynamically according to your instructions. # intro to the elements panel This panel centralizes the management of each element of your Web Application. - **Hierarchical listing:** Elements are organized in a tree based on their hierarchy in the Webflow page structure, making navigation and searching easier. - **Accessing configurations and events:** Clicking on an item in the panel takes you to its settings panel, where you can: - Configure element behavior : Define how it will look and behave in different situations. - Add Events : Associate events such as `On Click`, `On Change` or others to the element to trigger specific actions when the user interacts with it. ::: tip Note For more information about how this panel works, refer to [elements events](../elements/events) and [element configurations](../elements/configurations) ::: # Intro to the element events Element events are triggers that work with the interactions that the your user performs on your website, such as clicking, hovering on an element, entering a value in an input field or submitting a form, etc. Wized allows you to `listen` to these events and create action flows to respond to them. ::: info Note Element events must be linked to an element that contains the [Wized attribute](/start-here/getting-started/wized-attribute). For events not linked to a specific element, use [Global events](/global-events/) instead. ::: ## Setting up an event ### 1. Select the element In the Wized elements panel, click on the element. ![elements_overview](elements_overview.png) ### 2. Go to events section In the right panel, click on the lightning icon. ![add_event_overview](add_event_overview.png) ### 3.Choose the event use the dropdown menu to select the event you want to `listen` to. You can choose from a wide variety of standard JavaScript events, such as `click`, `submit`, `change`, `input`, `focus`, `blur`, `keydown`, etc. Check the [full list](https://www.w3schools.com/js/js_htmldom_events.asp). ![event_types](event_types.png) ### 4. Select the action Choose the action you want Wized to execute when the event is triggered. You can create complex flows with more than one action in the same event. You can rearrange actions by dragging and dropping them. You can also enable or disable them using the toggle, controlling whether they execute when the event occurs. ::: tip Order matters Keep in mind that the actions are executed in the order in which they are in the event. ::: ![actions_list](actions_list.png) ### 5. Set up the action Depending on the action you have chosen, specific parameters will appear that you must set. ## Most common events To use any of these events, just type the name of the event in the dropdown, even if it does not appear in the dropdown options. ### Mouse events - **click** → Triggered when an element is clicked - **dblclick** → Triggered when an element is double-clicked - **mouseenter / mouseleave** → Triggered when the mouse enters or leaves an element - **mouseover / mouseout** → Similar to `mouseenter/mouseleave` but bubbles --- ### Keyboard events - **keydown** → Triggered when a key is pressed - **keyup** → Triggered when a key is released --- ### Form events - **submit** → Triggered when a form is submitted - **input** → Triggered when a user types in an input field - **change** → Triggered when the value of an input/select changes --- ### Window events - **load** → Triggered when the page fully loads - **resize** → Triggered when the window is resized - **scroll** → Triggered when the user scrolls --- ### Touch events (Mobile) - **touchstart** → Triggered when a user touches the screen - **touchmove** → Triggered when a user moves their finger on the screen - **touchend** → Triggered when a user lifts their finger ## Actions Actions are tasks that Wized performs in response to a user-triggered event. When a user interacts with an element (e.g., clicks a button, types in an input field, hovers over an element), an event is fired, and one or more actions can be executed. Actions can be **chained together**, meaning you can execute multiple actions in sequence. Additionally, each action can have **optional conditions**, allowing you to define rules that determine whether an action should be executed. ::: tip Note - This events focuses on actions triggered by **user interaction events** (e.g., clicking, input changes, form submissions). It does not cover [global events](/global-events/) like "on page load." - Actions are executed in sequence, one action is executed only when the previous one has been completed. ::: --- ## Available actions ### Set Cookie Stores or updates a cookie value in the user's browser. useful for remembering user preferences or tracking interactions. #### Example use cases: - Save a user’s theme preference when they toggle between light and dark mode. - Store a user’s preferred language when they select it from a dropdown. #### Example: **Event:** `click` on a toggle button **Action:** Store the selected theme in a cookie ::: info Note Make sure you've created at least one cookie, as you'll need to select the cookie you want to update from the dropdown, where all created cookies will be listed ::: --- ### Set variable Updates the value of a variable in Wized. This is useful for temporarily storing user selections or form inputs. #### Example use cases: - Store the selected product ID when a user clicks on a product. - Track the number of times a user clicks a button. #### Example: **Event:** `click` on a product card **Action:** Save the selected product ID in a variable ::: info Note Make sure you've created at least one variable, as you'll need to select the variable you want to update from the dropdown, where all created variables will be listed ::: --- ### Custom function Executes a JavaScript function to perform advanced operations, such as formatting data or interacting with other scripts. #### Example use cases: - Format user input before displaying it. - Validate a form field before allowing submission. #### Example: **Event:** `input` in a text field **Action:** Format user input to capitalize the first letter ::: warning Note Custom code is a powerful tool, but keep in mind that Wized doesn’t validate it. Make sure your code is well-structured to avoid unexpected behavior. ::: --- ### Perform a request Sends an HTTP request to an API to fetch or send data. This is useful for interacting with external services. #### Example use cases: - Fetch product details when a user selects an item from a list. - Submit form data when a user clicks the "Submit" button. #### Example: **Event:** `change` in a dropdown **Action:** Fetch product details from an API ::: info Note Make sure you've created at least one [request](/requests/), as you'll need to select the request you want to perform from the dropdown. ::: ## Action flows (chaining actions) One of the most powerful features of Wized is the ability to **chain multiple actions** into a sequence. This allows you to create dynamic, complex workflows that execute step by step in response to a single user interaction. ### Why use action flows? - **Sequential execution** → Actions run in order, ensuring logical dependencies. - **Conditional logic** → You can define conditions that determine whether an action should execute or not. - **Flexible customization** → Actions can be mixed and matched to fit any interaction scenario. ### Example `Product selection flow` **Event:** When a user **clicks on a product card**, the flow: 1. **Stores the selected product ID** in a variable. 2. **Fetches product details** via an API request. 3. **Set a variable** (using a condition if stock > 1). 4. **If in stock, updates the UI** with a success message ## Disabling events and actions To disable temporarily element events and actions without deleting them you can use the disable switch in header. You can use this feature to pause certain functionalities and re-enable them later as needed. ![disable-events](disable-functionality.png) # Intro to the elements In Wized, elements refer to the HTML elements you've created in Webflow that include the [wized attribute](/start-here/getting-started/wized-attribute). These elements are recognized within the configurator, allowing you to add or customize specific [configurations](/elements/configurations) and [events](/elements/events) to fit your needs. ::: tip Note Make sure you have added the [wized attribute](/start-here/getting-started/wized-attribute) first to all the elements you want to configure in Wized ::: ## Wized elements In Wized, elements are the core building blocks of your website, replicated from your Webflow project. Wized renders your site within its configurator, allowing you to enhance these existing elements by adding logic, configurations, and events. This interaction transforms your static design into a dynamic experience, enabling you to create advanced functionalities without modifying your original Webflow structure. ### Element configurations These are all the possible [configurations](/elements/configurations) that allow the element to have a dynamic behavior according to your indications. Examples of configurations include: hiding or showing an element, rendering a list of elements, setting dynamic texts, and dynamically modifying HTML attributes, among others. These configurations alter the behavior of the element based on the conditions you determine. ### Element events [Events](/elements/events) allow actions to be triggered when the end user interacts with the elements. For example, when a user clicks on an element or hovers over it, you can create sequential flows that execute in response, such as running a request, updating the value of a cookie or variable, etc. ## Reactivity in Wized Wized has the ability to instantly react to changes in your web app. Whenever any change in the state of your application is modified (for example, by changing the value of a variable or cookie or receiving a response from an API), Wized automatically re-evaluates all the conditions you have defined. If the result of any condition changes, Wized instantly updates the appearance or behavior of the relevant elements, without requiring a page reload. # Intro to the array methods ::: tip Note In the function editor, you can perform any [JS method](https://www.w3schools.com/js/js_array_methods.asp), using any value from cookies, variables, parameters, request responses, inputs or forms. Be sure to use the [parameters](/function-editor/parameters) correctly. ::: ## push() **Description** Adds one or more elements to the end of an array. Ideal for dynamically updating lists (e.g., adding new items to a cart). ::: info Note In this example, `return` is not used because the operation is executed once it is written, use `return` only if, in addition to this, you need to use the value of the new array. ::: ![array-push-example](array-push-example.png) ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const cart = ['apple', 'bread']; cart.push('milk'); // Result: ["apple", "bread", "milk"] return cart; // Optional, only if you want to return the array with the new elements to use it. ``` ## pop() **Description** Removes the **last element** from an array and returns it. Useful for LIFO (Last-In-First-Out) operations like undo stacks. ::: info Note In this example, `return` is not used because the operation is executed once it is written, use `return` only if, in addition to this, you need to use the value of the new array. ::: ![array-pop-example](array-pop-example.png) ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const tasks = ['task1', 'task2', 'task3']; tasks.pop(); // tasks: ["task1", "task2"], lastTask: "task3" retrun tasks; // Optional, only if you want to return the new array to use it. ``` ## map() **Description** Creates a new array by applying a function to every element. Perfect for transforming data (e.g., formatting prices or user names). ![array-map-example](array-map-example.png) ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const numbers = [1, 2, 3]; const doubled = numbers.map((num) => num * 2); // Result: [2, 4, 6] return doubled; ``` ## filter() **Description** Creates a new array with elements that pass a test. Use to extract subsets (e.g., active users, products in stock). ![array-filter-example](array-filter-example.png) ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const users = [ { name: 'Alice', active: true }, { name: 'Bob', active: false }, ]; return users.filter((user) => user.active); // Result: [ { name: "Alice", active: true } ] ``` ## forEach() **Description** Executes a function for each array element. Used for side effects like rendering UI components or logging. ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const colors = ['red', 'green', 'blue']; colors.forEach((color) => console.log(color)); // Logs: "red", "green", "blue" ``` ## find() **Description** Returns the **first element** that satisfies a condition. Great for searching (e.g., fetching a user by ID). ![array-find-example](array-find-example.png) ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const products = [ { id: 1, name: 'Laptop' }, { id: 2, name: 'Phone' }, ]; return products.find((p) => p.id === 1); // Result: { id: 1, name: "Laptop" } ``` ## reduce() **Description** Reduces an array to a single value by applying a function cumulatively. Use for totals, averages, or flattening data. ![array-reduce-example](array-reduce-example.png) ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const purchases = [10, 20, 30]; return purchases.reduce((sum, price) => sum + price, 0); // Result: 60 ``` ## includes() **Description** Checks if an array contains a specific value. Simple alternative to `indexOf` for presence checks (case-sensitive). ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const roles = ['admin', 'editor', 'viewer']; return roles.includes('admin'); // Result: true ``` ## slice() **Description** Copies a portion of an array into a new array. Non-destructive way to extract data (e.g., pagination). ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const data = [1, 2, 3, 4, 5]; return data.slice(0, 2); // Result: [1, 2] ``` ## splice() **Description** Adds/removes elements at a specific position. Use cautiously (mutates the original array). ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const tasks = ['taskA', 'taskB', 'taskC']; return tasks.splice(1, 1, 'taskX'); // Removes 1 element at index 1, adds "taskX" // Result: ["taskA", "taskX", "taskC"] ``` # Intro to the conditional methods ## `if` statement **Description** Executes a block of code if a specified condition is truthy. Foundation of decision-making in logic. ![conditionals-if-example](conditionals-if-example.png) ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const userAge = 20; let hasAccess = false; if (userAge >= 18) { hasAccess = true; } return hasAccess; ``` ## `else` clause **Description** Provides an alternative code block to execute if the `if` condition is falsy. ![conditionals-if-else-example](conditionals-if-else-example.png) ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const userAge = 12; if (userAge >= 18) { return (hasAccess = true); } else { return (hasAccess = false); } ``` ## Ternary operator (`? :`) **Description** Shorthand for simple `if-else`. Returns one of two values based on a condition. ![conditionals-ternary-example](conditionals-ternary-example.png) ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const userAge = 12; return userAge >= 18 ? 'Welcome' : "You can't join"; ``` ## `else if` ladder **Description** Tests multiple conditions sequentially after an initial `if`. Stops at the first truthy condition. ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const score = 85; let grade = ''; if (score >= 90) { grade = 'A'; } else if (score >= 80) { grade = 'B'; } else { grade = 'C'; } return grade; // result: "B" ``` ## `switch` statement **Description** Compares a value against multiple cases. Use for readability with many fixed conditions. ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const day = 'Monday'; let activity = ''; switch (day) { case 'Monday': activity = 'Play guitar'; break; case 'Friday': activity = 'Play soccer'; break; default: activity = 'Play tennis'; } return activity; // return: "Play guitar" ``` # Intro to the date methods ::: tip Note In the function editor, you can perform any [JS method](https://www.w3schools.com/js/js_date_methods.asp), using any value from cookies, variables, parameters, request responses, inputs or forms. Be sure to use the [parameters](/function-editor/parameters) correctly. ::: ## Date.now() **Description** Returns the current timestamp in milliseconds (since January 1, 1970). Used for timing operations or unique IDs. ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ return (timestamp = Date.now()); // Result: 1718035200000 (example value) ``` ## getFullYear() **Description** Extracts the year (4 digits) from a Date object. Ideal for age calculations or date displays. ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const today = new Date(); return today.getFullYear(); // Result: 2025 (current year) ``` ## getMonth() **Description** Returns the month of a Date object (0 = January, 11 = December). Combine with `+1` for human-readable formats. ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const date = new Date('2025-02-25'); return date.getMonth() + 1; // Result: 2 (Feb) ``` ## getDate() **Description** Gets the day of the month (1-31) from a Date object. Useful for deadlines or calendar features. ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const eventDate = new Date('2025-02-25'); return eventDate.getDate(); // Result: 25 ``` ## getHours() & getMinutes() **Description** - `getHours()`: Returns the hour (0-23) of a Date object. - `getMinutes()`: Returns the minutes (0-59). ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const now = new Date(); return now.getHours(); // 14 (2 PM) const minutes = now.getMinutes(); // 30 ``` ## toISOString() **Description** Converts a Date object to an ISO 8601 string (e.g., `"2024-07-20T12:00:00.000Z"`). Standard format for APIs and databases. ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const date = new Date(); return date.toISOString(); // Result: "2024-07-20T12:00:00.000Z" ``` ## toLocaleDateString() **Description** Converts a Date object to a locale-specific date string. Customizable for regional formats (e.g., `"07/20/2024"` vs `"20/07/2024"`). ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const date = new Date(); return date.toLocaleDateString('en-US'); // Result: "7/20/2024" ``` # Intro to the math formulas ::: tip Note In the function editor, you can perform any [JS method](https://www.w3schools.com/js/js_math.asp), using any value from cookies, variables, parameters, request responses, inputs or forms. Make sure to use the [parameters](/function-editor/parameters) correctly. ::: ## Math.abs() **Description** Returns the absolute value of a number (removes negative sign if present). Useful for distance calculations or non-negative contexts. ![math-abs-example](math-abs-example.png) ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const number = -7.25; return Math.abs(number); // Result: 7.25 ` ``` ## Math.round() **Description** Rounds a number to the nearest integer. Perfect for simplifying decimal results (e.g., prices, ratings). ![math-round-example](math-round2.png) ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const price = 9.87; return Math.round(price); // Result: 10 ` ``` ## Math.ceil() **Description** Rounds a number **up** to the nearest integer. Ideal for ensuring minimum capacity (e.g., seats, resources). ![math-ceil-example](math-ceil-example.png) ````javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const users = 15.1; return Math.ceil(users / 10); // Result: 2 (for 15.1/10 = 1.51 → rounded up) ``` ```` ## Math.floor() **Description** Rounds a number **down** to the nearest integer. Used for truncating decimals (e.g., age calculations). ![math-floor-example](math-floor-example3.png) ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const age = 29.9; return Math.floor(age); // Result: 29 ``` ## Math.max() **Description** Returns the largest value from a list of numbers. Helpful for comparisons (e.g., finding highest scores). ![math-max-example](math-max-example.png) ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ return Math.max(4, 12, 3, 9); // Result: 12 ``` ## Math.min() **Description** Returns the smallest value from a list of numbers. Useful for constraints (e.g., discounts, limits). ![math-min-example](math-min-example.png) ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ return Math.min(4, 12, 3, 9); // Result: 3 ``` ## Math.random() **Description** Generates a random decimal between 0 (inclusive) and 1 (exclusive). Combine with other methods for custom ranges. ![math-random-example](math-random-example.png) ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const randomNum = Math.random(); const diceRoll = Math.floor(randomNum * 6) + 1; // Result: Random integer between 1-6 `; return diceRoll; ``` ## Math.pow() **Description** Calculates the base raised to an exponent (baseexponent). Used for growth calculations or geometric operations. ![math-pow-example](math-pow-example.png) ````javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ return Math.pow(2, 3); // Result: 8 (2³ = 2*2*2) ``` ```` # Intro to the number methods ::: tip Note In the function editor, you can perform any [JS method](https://www.w3schools.com/js/js_number_methods.asp), using any value from cookies, variables, parameters, request responses, inputs or forms. Make sure to use the [parameters](/function-editor/parameters) correctly. ::: ## toFixed() **Description** Formats a number with a fixed number of digits after the decimal point. Ideal for currency, measurements, or consistent decimal displays. ![number-fixed-example](number-fixed-example.png) ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const price = 5.567; return price.toFixed(2); // Result: "5.57" (rounded to 2 decimals) ``` ## toPrecision() **Description** Formats a number to a specified length of significant digits. Useful for scientific data or limiting display length. ![number-precision-example](number-precision-example2.png) ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const value = 123.456; return value.toPrecision(4); // Result: "123.5" (4 significant digits) ``` ## toString() **Description** Converts a number to a string, optionally in a specific base (e.g., binary, hexadecimal). Helpful for encoding or UI displays. ![number-toString-example](number-toString-example.png) ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const decimalNumber = 255; return decimalNumber.toString(16); // Result: "ff" (hexadecimal representation) ``` ## Number.parseInt() **Description** Parses a string and returns an integer in a specified base (default: base 10). Ignores non-numeric suffixes. ![number-parseInt-example](number-parseInt-example.png) ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const pixelValue = '42px'; return Number.parseInt(pixelValue); // Result: 42 ``` ## Number.parseFloat() **Description** Parses a string and returns a floating-point number. Extracts decimals and ignores non-numeric suffixes. ![number-parseFloat-example](number-parseFloat-example.png) ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const userInput = '3.14meters'; return Number.parseFloat(userInput); // Result: 3.14 ``` ## Number.isInteger() **Description** Checks if a value is an integer. Returns `true` or `false`. Useful for validation (e.g., age, quantity inputs). ![number-isInteger-example](number-isInteger-example.png) ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const value1 = 42; const value2 = 42.5; return Number.isInteger(value1); // true Number.isInteger(value2); // false ``` ## Number.isNaN() **Description** Checks if a value is `NaN` ("Not-a-Number"). Safer than the global `isNaN()` (doesn’t coerce non-number types). ![number-isNaN-example](number-isNaN-example.png) ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const invalidCalc = 0 / 0; return Number.isNaN(invalidCalc); // true ``` # Intro to the object methods ::: tip Note In the function editor, you can perform any [JS method](https://www.w3schools.com/Js/js_object_methods.asp), using any value from cookies, variables, parameters, request responses, inputs or forms. Make sure to use the [parameters](/function-editor/parameters) correctly. ::: ## Object.keys() **Description** Returns an array of a given object’s own property names (keys). Useful for iterating through object properties dynamically. ![object-keys-example](object-keys-example.png) ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const user = { name: 'Alice', age: 30 }; return Object.keys(user); // Result: ["name", "age"] ``` ## Object.values() **Description** Returns an array of a given object’s own property values. Perfect for extracting data without keys (e.g., lists, summaries). ![object-values-example](object-values-example.png) ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const user = { name: 'Alice', age: 30 }; return Object.values(user); // Result: ["Alice", 30] ``` ## Object.entries() **Description** Returns an array of a given object’s key-value pairs as arrays `[key, value]`. Ideal for data transformations or table displays. ![object-entries-example](object-entries-example.png) ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const user = { name: 'Alice', age: 30 }; return Object.entries(user); // Result: [["name", "Alice"], ["age", 30]] ``` ## Object.assign() **Description** Copies properties from one or more source objects to a target object. Used to merge objects or clone data (shallow copy). ![object-assign-example](object-assign-2.png) ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const defaults = { theme: 'light', fontSize: 12 }; const userSettings = { fontSize: 14 }; return Object.assign({}, defaults, userSettings); // Result: { theme: "light", fontSize: 14 } ``` ## Object.freeze() **Description** Prevents modifications to an object (add/update/delete properties). Ensures data integrity for constants or configurations. ![object-freeze-example](object-freeze-example.png) ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const config = { apiUrl: 'https://api.example.com' }; Object.freeze(config); config.apiUrl = 'https://hacked.url'; // Fails silently in non-strict mode // config remains unchanged ``` ## hasOwnProperty() **Description** Checks if an object has a specific property as its own (not inherited from prototypes). Critical for safe property checks. ![object-hasOwnProperty-example](object-hasOwnProperty-example.png) ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const user = { name: 'Alice' }; return user.hasOwnProperty('name'); // true return user.hasOwnProperty('age'); // false ``` # Intro to the operator methods ::: tip Note In the function editor, you can perform any [JS method](https://www.w3schools.com/js/js_operators.asp)using values from cookies, variables, parameters, request responses, inputs, or forms. Be sure to use the [parameters](/function-editor/parameters) correctly. ::: ## Addition (`+`) **Description** Adds two numbers or concatenates strings. Be cautious: mixing numbers and strings triggers type coercion. ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ return (sum = 3 + 5); // 8 return (text = 'Price: $' + 99); // "Price: $99" ``` ## Subtraction (`-`) **Description** Subtracts two numbers. Converts strings to numbers if possible (e.g., `"5" - 2 → 3`). ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ return (result = 10 - 3); // 7 ``` ## Multiplication (`*`) **Description** Multiplies two numbers. Non-numeric values are coerced to numbers (e.g., `"2" * "3" → 6`). ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ return (total = 4 * 5); // 20 ``` ## Division (`/`) **Description** Divides two numbers. Returns `Infinity` if divided by 0. ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ return (quotient = 15 / 3); // 5 ``` ## Modulus (`%`) **Description** Returns the remainder of a division. Useful for even/odd checks or cyclic patterns. ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ return (remainder = 10 % 3); // 1 (10 ÷ 3 = 3 with remainder 1) ``` ## Exponentiation (`**`) **Description** Raises a base to the power of an exponent (e.g., `2 ** 3 → 8`). ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ return (power = 2 ** 4); // 16 ``` ## Increment (`++`) **Description** Increases a number by 1. Use as prefix (`++x`) or postfix (`x++`). ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ let count = 5; return count++; // count becomes 6 ``` ## Decrement (`--`) **Description** Decreases a number by 1. Use as prefix (`--x`) or postfix (`x--`). ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ let count = 5; return count--; // count becomes 4 ``` ## Equality (`==`) **Description** Compares values **with type coercion** (e.g., `5 == "5" → true`). Avoid in most cases. ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ return 5 == '5'; // true ``` ## Strict Equality (`===`) **Description** Compares values **and types** (no coercion). Preferred for reliable comparisons. ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ return 5 === '5'; // false ``` ## Inequality (`!=`) **Description** Checks if values are different **with type coercion**. ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ return 5 != '5'; // false (due to coercion) ``` ## Strict Inequality (`!==`) **Description** Checks if values or types differ (no coercion). Safer than `!=`. ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ return 5 !== '5'; // true ``` ## Greater Than (`>`) & Less Than (`<`) **Description** Compares numeric values or string lexicographical order. ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ return 10 > 5; // true return 'apple' < 'banana'; // true (a < b alphabetically) ``` ## Greater Than or Equal (`>=`) & Less Than or Equal (`<=`) **Description** Similar to `>`/`<` but includes equality. ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ return 5 >= 5; // true ``` ## Logical AND (`&&`) **Description** Returns `true` if **both** operands are truthy. Returns the first falsy value or last truthy. ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ return true && 5 > 3; // true ``` ## Logical OR (`||`) **Description** Returns `true` if **at least one** operand is truthy. Returns the first truthy value. ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ return false || 'default'; // "default" ``` ## Logical NOT (`!`) **Description** Inverts a boolean value. Converts truthy/falsy values to boolean. ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ return !true; // false ``` ## Assignment (`=`) **Description** Assigns a value to a variable. ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ let x = 10; return x; ``` ## Add & Assign (`+=`) **Description** Adds a value to a variable and updates it. ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ let total = 5; return (otal += 3); // total = 8 ``` ## Ternary Conditional (`? :`) **Description** Shorthand for `if-else`. Syntax: `condition ? exprIfTrue : exprIfFalse`. ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const access = age >= 18 ? 'Granted' : 'Denied'; return access; ``` ## Nullish Coalescing (`??`) **Description** Returns the right-hand operand if the left is `null` or `undefined`. ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ return i.login_name ?? 'Guest'; ``` ## Optional Chaining (`?.`) **Description** Safely accesses nested properties. Returns `undefined` if any chain link is `null`/`undefined`. ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ return r.request_name.data.user?.address?.city; ``` ## typeof **Description** Returns a string indicating the type of a variable. ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ return typeof 'hello'; // "string" ``` ## Spread (`...`) **Description** Expands arrays/objects into individual elements. Used for copying, merging, or function arguments. ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const merged = [...arr1, ...arr2]; return merged; ``` ## Nullish Assignment (`??=`) **Description** Assigns a value only if the variable is `null`/`undefined`. ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ let config = null; return (config ??= { theme: 'light' }); // config becomes { theme: "light" } ``` ## Logical AND Assignment (`&&=`) **Description** Assigns a value only if the variable is truthy. ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ let value = 'Hello'; return (value &&= 'Updated'); // value becomes "Updated" ``` ## in **Description** Checks if a property exists in an object. ```javascript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ return 'name' in { name: 'Alice' }; // true ``` # Intro to the text formulas In Wized, you can transform text with the [Function Editor](/function-editor/). Whether you need to modify values from [cookie](/data-store/cookies), [variables](/data-store/variables), [parameters URL](/data-store/navigation), [request responses](/data-store/requests), etc. You can apply some JS methods directly within the Function editor. This allows you to dynamically format, extract or manipulate text to suit your needs. In this guide, we will explore the most commonly used key [JavaScript methods](https://www.w3schools.com/js/js_string_methods.asp), along with practical examples to help you apply them in your project. ::: tip Note In the function editor, you can perform any [JS method](https://www.w3schools.com/js/js_string_methods.asp), using any value from cookies, variables, parameters, request responses, inputs or forms. Make sure to use the [parameters](/function-editor/parameters) correctly. ::: ## toLowerCase() **Description** Converts all characters in a text to lowercase. Useful for normalizing data or case-insensitive comparisons. ![toLowerCase-example](toLowerCase-example.png) ```JavaScript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const originalText = "Hello World"; return originalText.toLowerCase(); // Result: "hello world" ``` ## toUpperCase() **Description** Transforms all characters in a text to uppercase. Ideal for standardizing formats or highlighting information in interfaces. ![toUpperCase-example](toUpperCase-example.png) ```JavaScript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const originalText = "Wized is a Framework"; return originalText.toUpperCase(); // Result: "WIZED IS A FRAMEWORK" ``` ## concat() **Description** Combines two or more texts into one. An alternative to the `+` operator, offering better readability for multiple concatenations. ![concatenate-text-example](concatenate-text-example.png) ```JavaScript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const greeting = "Hello, "; const user = "John"; const message = greeting.concat(user, "!"); return message; // Result: "Hello, John!" ``` ## trim() **Description** Removes whitespace from the start and end of a text. Essential for cleaning user inputs or form data. ![trim-example](trim-example.png) ```JavaScript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const textWithSpaces = " example text "; return cleanText = textWithSpaces.trim(); // Result: "example text" ``` ## split() **Description** Splits a text into parts using a specified separator (like a comma, space, or special character) and returns an array of the fragments. ![split-example](split-example.png) ```JavaScript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const list = "apple,banana,grape"; return fruitArray = list.split(","); // Result: ["apple", "banana", "grape"] ``` ## replace() **Description** Replaces the first occurrence of a text or pattern within a string. Supports regular expressions for advanced searches. ![replace-example](replace-example.png) ```JavaScript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const originalText = "User: guest123"; return modifiedText = originalText.replace("guest123", "admin"); // Result: "User: admin" ``` ## includes() **Description** Checks if a text contains a specific substring. Returns `true` or `false`. Case-sensitive by default (use `toLowerCase()` first for case-insensitive checks). ![includes-example](includes-example.png) ```JavaScript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const message = "Welcome to Wized"; return hasWized = message.includes("Wized"); // Result: true ``` ## slice() **Description** Extracts a section of a text based on start and end indexes. ![slice-example](slice-example.png) ```JavaScript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const code = "ID-2024-X"; return subCode = code.slice(3, 7); // Result: "2024" ``` ## replaceAll() **Description** Replaces all occurrences of a text or pattern in a string. Global version of `replace()`. ![replace-all-example](replace-all-example.png) ```JavaScript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const originalText = "Error: null, Error: undefined"; return originalText.replaceAll("Error", "Warning"); // Result: "Warning: null, Warning: undefined" ``` ## startsWith() & endsWith() **Description** - `startsWith()`: Checks if a text starts with specific characters. ![startsWith-example](startsWith-example.png) ```JavaScript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const url = "https://wized.com"; return isSecure = url.startsWith("https"); // result true ``` - `endsWith()`: Checks if a text ends with specific characters. ![endsWith-example](endsWith-example.png) ```JavaScript /* Keep in mind that this example has fixed values, however, you can replace any value with a value from a cookie, variable, form, input, etc. */ const text = "https://wized.com"; return text.endsWith(".com"); // result true ``` # Basic concepts In this guide you will learn what are the basic concepts you need to understand to correctly use the function editor. ## `Return` keyword In the Wized Function editor, it is essential to always use the `return` keyword. This word indicates the value that a function should return at the end of its execution. ::: warning Important You must **always include the** `return` keyword at the end of your functions. Make sure that you do not duplicate `return` in the same function. ::: ::: details returning Numbers example - **Returning numbers** To return a numeric value, you would use: ![num example](num-example.png) ```javascript const number_value = 42; return number_value; // This will return the number 42 ``` ::: ::: details returning strings example To return a string, you can provide a text value enclosed in quotes: ![text example](text-example.png) ```javascript return 'Hello, World!'; // This will return the string 'Hello, World!' ``` ::: ::: details returning Booleans example To return a boolean value, you can simply return `true` or `false`: ![boolean example](boolean-example.png) ```javascript const isLoggedIn = true; return isLoggedIn; // This will return true ``` ::: ## `let` and `const` keywords You can use `let` and `const` to define variables in JavaScript. Here’s the difference: - **`let`**: Used to declare variables whose value can change later. ```javascript let counter = 0; counter = 5; // Valid, because "let" allows reassignment ``` - **`const`**: Used to declare variables whose value will not change after being assigned. ```javascript const PI = 3.1416; PI = 3.14; // ❌ Error: Cannot reassign a value to a constant ``` ## Dot notation The dot notation is a method for accessing specific properties within [objects](/function-editor/data-types#objects) and [arrays](/function-editor/data-types#arrays-lists) in JavaScript. [Reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_accessors) ### How does It work? Consider your data as a tree structure, where each branch represents a property and each leaf corresponds to a value. Dot notation allows you to "navigate" this tree by specifying the path from the root to the desired leaf. ::: details example accessing an object value ![dot-notation-object-example](dot-notation-object-example.png) For example, if you have a user object with properties like `name` and `email`, you can access these properties using dot notation as follows: ```javascript const user = { name: 'John Doe', // User's name email: 'john.doe@example.com', // User's email }; return user.name; // Returns 'John Doe' return user.email; // Returns 'john.doe@example.com' ``` ::: ::: details example accessing an array object value ![dot-notation-array-example](dot-notation-array-example.png) Additionally, dot notation is not only used for objects but also for arrays. Here is an example of how to access a value within an array using dot notation: ```javascript const users = [ { name: 'John Doe', email: 'john.doe@example.com' }, { name: 'Jane Smith', email: 'jane.smith@example.com' }, ]; // Accessing the name of the first user return users[0].name; // Returns 'John Doe' // Accessing the name of the second user return users[1].name; // Returns 'Jane Smith' ``` ::: --- ## Operators and expressions Operators are used to perform calculations and comparisons in your JavaScript code. Below are the principal categories of operators you will encounter: ### Arithmetic operators: These include `+`, `-`, `*`, `/`, and `%`, which perform addition, subtraction, multiplication, division, and modulus (remainder of division), respectively. ::: details Subtraction example ![Substraction example](subtraction-example.png) ```JavaScript // Subtraction: Calculate remaining stock let initialStock = 10; // You can replace this value by any other value such as variables, cookies, request responses, etc. let soldItems = 5; // fixed number of items sold return remainingStock = initialStock - soldItems; // subtract sold items from stock ``` ::: ::: details Multiplication example ![multiplication example](multiplication-example.png) ```JavaScript // Multiplication: Calculate interest on product price let productPrice = 200; // fixed product price let interestRate = 3; // You can replace this value by any other value such as variables, cookies, request responses, etc. return totalWithInterest = productPrice * interestRate; // multiply price by interest rate ``` ::: ::: details Division example ![division example](division-example.png) ```Javascript // Subtraction: Calculate remaining stock with variable let initialStock = v.initialStock; // stock variable let soldItems = 5; // fixed number of items sold return remainingStock = initialStock - soldItems; // subtract sold items from stock // Multiplication: Calculate interest on product price from API response let productPrice = 200; // fixed product price let interestRate = r.getInterest.data; // interest rate from an API request response return totalWithInterest = productPrice * interestRate; // multiply price by interest rate // Division: Calculate average score from a sum of scores let sumOfScores = v.totalScores; // total scores variable let numberOfTests = 4; // fixed number of tests return averageScore = sumOfScores / numberOfTests; // divide total scores by number of tests ``` ::: ::: warning Note Make sure that if you are going to use variable values, cookies, responses to requests, etc. They must be already created and contain a value with a valid format. ::: ### Comparison operators: These include `>`, `<`, `>=`, `<=`, `==`, `!=`, `===`, and `!==`. They are used to compare values, determining if one is greater than, less than, equal to, or not equal to another. ::: details greater than example ![greater than example](greater-than-example.png) ```JavaScript // Greater than (>): Check if total points exceed a threshold let totalPoints = v.totalPoints; // variable storing total points let pointsThreshold = 100; // fixed threshold value return exceedsThreshold = totalPoints > pointsThreshold; // true if totalPoints is greater than pointsThreshold ``` ::: ::: details greater than or equal to example ![greater-than-or-equal-to](greater-than-or-equal-to.png) ```JavaScript // Greater than or equal to (>=): Check if cart total meets minimum for discount let cartTotal = 50; // total value of items in the cart let minForDiscount = 50; // minimum cart total for discount return qualifiesForDiscount = cartTotal >= minForDiscount; // true if cartTotal is at least minForDiscount ``` ::: ::: details equal to In JavaScript, the operators =, ==, and === have different functions: - `=` is the assignment operator. It is used to assign a value to a variable. ```JavaScript let x = 5; // x is now 5 ``` - `==` is the loose equality operator. It compares values but converts types if necessary. ```JavaScript 5 == "5"; // true (converts the string to a number before comparing) ``` - `===` is the strict equality operator. It compares both values and types, without conversions. ```JavaScript 5 === "5"; // false (one is a number, the other is a string) ``` - example ```JavaScript // Strict equal to (==): Check if API response status differs from success let responseStatus = r.request_name.status; // response status from an request let successStatus = 200; // success status code return isEqual = responseStatus == successStatus; // true if responseStatus is equal to successStatus ``` ::: ::: warning Note Make sure that if you are going to use variable values, cookies, responses to requests, etc. They must be already created and contain a value with a valid format. ::: ### Logical operators: These include `&&` (AND), `||` (OR), and `!` (NOT). They are used to combine or negate boolean expressions. ::: details && AND example ![and-example](and-example.png) ```JavaScript // AND (&&): Check if the `get_all_products` request was executed and successful. let hasRequested = r.get_all_products.hasRequested; // Boolean if the request has already been executed let successful = r.get_all_products.status === 200; // Boolean result of the validation if the get_all_products" request was successfully executed. return hasRequested && successful; // true, if hasRequested and successful are true ``` ::: ::: details OR (||) example ![or-example](or-example.png) ```JavaScript // OR (||): Check if product is in stock or if backorder is allowed let inStock = v.stock > 0; // boolean indicating if stock is available let allowBackorder = true; // boolean indicating if backorder is allowed return canPurchase = inStock || allowBackorder; // true if in stock or backorder allowed ``` ::: ::: details NOT (!) example ```JavaScript // NOT (!): Negate login status to check if user is not logged in let loggedIn = r.login.ok; // boolean indicating login status let isGuest = !loggedIn; // true if user is not logged in ``` ::: ::: details combined example ```JavaScript // Combined example: Check if user is an admin and either logged in or has a valid session let role = r.auth_user.data.role === "admin"; // boolean for admin role let loggedInStatus = r.auth_user.ok; // boolean for login status let validSession = v.session === "valid"; // boolean for valid session status return access = role && (loggedInStatus || validSession); // true if admin and (logged in OR has a valid session) ``` ::: ::: warning Note Make sure that if you are going to use variable values, cookies, responses to requests, etc. They must be already created and contain a value with a valid format. ::: ### Assignment operators: These operators (`=`,`+=`,`-=`,`*=`,`/=`,`%=`) allow you to assign a value to a variable or update its existing value: ::: details `=`: Assigns a value to a variable. ```JavaScript return counter = 10; //In this example a fixed value `10` was set, however, you can replace it by the value of a cookie, variable, URL parameter, request response, etc. ``` ::: ::: details `+=`: Adds a value to the current value of the variable. ```JavaScript let counter = 10; //In this example a fixed value `10` was set, however, you can replace it by the value of a cookie, variable, URL parameter, request response, etc. return counter +=1; ``` ::: ::: details `-=`: Subtracts a value from the current value of the variable. ```JavaScript let counter = 10; //In this example a fixed value `10` was set, however, you can replace it by the value of a cookie, variable, URL parameter, request response, etc. return counter -=1; ``` ::: ::: details `*=`: Multiplies the current value of the variable by a value. ```JavaScript let counter = 10; //In this example a fixed value `10` was set, however, you can replace it by the value of a cookie, variable, URL parameter, request response, etc. return counter *=1; ``` ::: ::: details `/=`: Divides the current value of the variable by a value. ```JavaScript let counter = 10; //In this example a fixed value `10` was set, however, you can replace it by the value of a cookie, variable, URL parameter, request response, etc. return counter /=1; ``` ::: ::: details `%=`: Calculates the modulus (remainder of division) ```JavaScript let counter = 10; //In this example a fixed value `10` was set, however, you can replace it by the value of a cookie, variable, URL parameter, request response, etc. return counter %=1; ``` ::: ## Conditionals (if...else) Conditionals allow you to execute different blocks of code depending on whether a condition is met or not. The basic structure of an if...else conditional is: ```JavaScript if (condition) { // Code to be executed if the condition is true } else { // Code to execute if the condition is false } ``` ::: details If-else example ![if-else-example](if-else-example.png) **example** ```JavaScript // example: Check if the user qualifies for a discount based on cart total let cartTotal = v.cartTotal; // variable storing the total value in the user's cart let discountThreshold = 50; // minimum cart total to qualify for a discount if (cartTotal >= discountThreshold) { // User qualifies for discount return "Congratulations! You qualify for a discount."; } else { // User does not qualify for discount return "Add more items to your cart to qualify for a discount."; } ``` ::: --- ## Ternary operators The ternary operator is a shorthand way of writing a simple conditional on a single line. Its structure is: ```JavaScript condition ? valueIfTrue : valueIfFalse ``` ::: details Ternary Operators example ![ternary-operators-example](ternary-example2.png) ```JavaScript // example: Check if the user qualifies for a discount using a ternary operator let cartTotal = v.cartTotal; // variable storing the total value in the user's cart let discountThreshold = 50; // minimum cart total to qualify for a discount // Ternary operator for discount qualification let message = cartTotal >= discountThreshold ? "Congratulations! You qualify for a discount." // value if true : "Add more items to your cart to qualify for a discount."; // value if false return message; ``` ::: # Data types guide ## Numbers Represents numeric values, which can be integers or decimals.In this [guide](https://www.w3schools.com/js/js_number_methods.asp), you will find some methods that you can use inside the [function editor](/function-editor/) with number data. :::info Note Go to Math [formulas](/formulas/math) to better understand how to work with this type of data ::: ## Strings Text strings represent sequences of characters, such as names, descriptions, messages, or any other type of textual information. In JavaScript, text strings are delimited by single ( ' ) or double ( " ) quotes. More information in this [guide](https://www.w3schools.com/js/js_string_methods.asp) :::info Note Go to Text [formulas](/formulas/text) to better understand how to work with this type of data ::: ## Booleans (true and false) Booleans represent logical values of `true` or `false`. They are essential for making decisions in your code and controlling the execution flow of your application. ## Objects An object is a data structure that stores information in key-value pairs. Each key is a unique identifier (a string) that points to a value, which can be of any data type (number, string, array, another object, etc.). ### How to identify an object? - It is written inside `{}` (curly braces). - Uses key-value pairs separated by colons `:`. - Keys are strings. - Values can be any data type. ### Creating an object You can create an object using curly braces `{}` and separating properties with commas. Each property has a key (name) and a value, separated by a colon `:`. For example: ```javascript const person = { name: 'John', age: 30, city: 'Madrid', }; // Object created with name, age and city properties return person; ``` You can check if a value is an object using: ```javascript return typeof person; // "object" ``` ### Accessing properties: You can access the value of a property of an object using [dot notation](/function-editor/basic-concepts#dot-notation). ### Modifying properties: If you need to change the value of an existing property, you can assign a new value to its key. For example: ```javascript person.age = 31; // Updates the value of the property "age" to 31 ``` ### Adding properties: You can add new properties to an object by assigning a value to a new key. For example: ```javascript person.profession = 'Developer'; // Adds the property "profession" to the object ``` ## Arrays An array is a data structure that stores multiple values in an ordered list. Each value is assigned a numeric index, starting from `0`. ### How to identify an array? - It is written inside `[]` (square brackets). - Elements are separated by commas. - The order of elements is maintained. ### Creating an array: To create an array, use square brackets `[]` and separate the elements with commas. For example: ```javascript return (myShoppingList = ['apples', 'milk', 'eggs', 'bread']); ``` ### Accessing elements: You can access a specific element in an array by using [dot notation](/function-editor/basic-concepts#dot-notation). ### Modifying elements: You can change the value of an existing element in an array by assigning it a new value using its index. For instance: ```javascript myShoppingList[1] = 'yogurt'; // Replace "milk" with "yogurt" ``` ### Types of content in an array Arrays can contain different types of values, including: - Numbers: `[1, 2, 3]` - Strings: `["apple", "banana", "cherry"]` - Booleans: `[true, false, true]` - Objects: `[{name: "Alice"}, {name: "Bob"}]` - Other arrays (Nested Arrays): `[[1, 2], [3, 4]]` :::info Note Go to array [formulas](/formulas/array) to better understand how to work with this type of data ::: # How to use AI to create code for Wized Artificial Intelligence can be an invaluable programming partner in Wized, assisting you in generating JavaScript code snippets quickly and efficiently. Even for those who are new to JavaScript or need to implement complex logic. To use AI effectively in Wized, it is crucial to provide the right context so that it understands the user's needs and generates code that is compatible. Here's how to do it: 1. **Identify the task:** Clearly define what the user wants to accomplish with the code. Is it to validate a form, display a conditional message, or perform a specific calculation? 2. **Ask a precise question:** Use clear and concise language to describe the task at hand. Include relevant details, such as the names of variables, cookies, or API responses that the user needs to utilize. 3. **Provide context to the AI:** Before asking the question, include the following prompt so that the AI understands the Wized environment and generates appropriate code: ## Snippet ```JavaScript You are assisting a Wized user, a low-code platform integrated with Webflow for creating interactive web applications. The user needs guidance writing JavaScript code within the Wized Function Editor to customize website behavior. Keep the following points in mind: - **Data Access:** Wized offers real-time access to data through specific parameters: - `c`: Cookies (e.g., `c.myCookie`) - `v`: Variables (e.g., `v.myVariable`) - `i`: Inputs (e.g., `i.myInputField`) - `f`: Forms (e.g., `f.myForm.name.email`) - `r`: API Responses (e.g., `r.myRequest.data.price`) - `n`: Navigation (e.g., `n.currentPage`) - **Functions:** Functions within the Function Editor must always return a value using the `return` keyword. - **Syntax:** Ensure the code is valid JavaScript and supported by modern web browsers. - **No `console.log`:** Avoid `console.log` statements, as Wized provides a built-in preview for results. - **No direct DOM access:** Do not use `document.getElementById` or similar DOM access methods, as Wized automatically manages element selection. Now, provide the user with Wized-compatible JavaScript code to answer their question. ``` ## Tips for better results with AI - **Be specific and detailed in your questions:** The clearer and more precise your task description is, the better the AI-generated code will be. - **Include examples:** If possible, provide examples of how you would like the end result to look or function. - **Mention relevant actions or settings:** If your code is related to a specific Wized action or setting, please mention this in your question so the AI can generate more contextualized code. # Intro to the funtion editor The **function editor** is a core component of the Wized configurator, designed specifically to empower you to create custom logic and enhance the interactivity of your web applications. While Wized offers a range of predefined [configurations](/elements/configurations), [events](/global-events/), and [actions](/global-events/actions-available) essential for any web application, it is important to provide these configurations with personalized context. Understanding when and how these configurations, actions, and events will execute is key to optimizing your application’s functionality. In this guide, you will learn how to utilize the function editor, as well as how it integrates with events, actions, and element configurations. ![function editor](function-editor-overview.png) # Window overview The **function editor** is organized into two main areas, designed to enhance your coding experience and facilitate result visualization. ![Function Editor](function-editor-overview.png) ## Text area In the **Text area**, you can write JavaScript functions that execute within Wized. This editor operates similarly to traditional code editors. Within the Wized environment, you have access to [specific parameters](/function-editor/parameters) that allow you to interact directly with the application's state data. ![text-area](text-area.png) ## Result area The **Result area** shows the output of your code after execution. By clicking the **Test button**, the code in the Text area executes, and the returned data is presented in various formats, including text, numbers, arrays, and objects. Some specific use cases for each format are: ![result-panel](result-panel.png) :::tip Note You can expand or collapse each property of an object or array, making it easier to analyze data and providing better visual control over the results. ::: ## Buttons area ![buttons](buttons.png) - **Test**: Executes the code written in the Text area and updates the Result area with the output area. - **Open data store**: Opens a floating window displaying the current contents of the Data store. - **Prettify**: Improves code readability by automatically formatting it. - **Documentation**: Shortcut to Wized documentation - **Wrap code**: Resizes the code to fit the window, eliminating the need for horizontal scrolling. # Into to the function editor parameters The parameters in Wized allow easy access to all types of data within the [function editor](/function-editor/). Each parameter represents a specific type of data. ## c: Access to cookies - ```javascript return c; //Returns an array with all cookies and their values ``` - ```javascript return c.cookie_name: //Returns the specific value of the indicated cookie. For more information, refer to the Cookies section. ``` ## f: Access to forms - ```javascript return f: // Returns an array of all created forms, where each form is an object that includes inputs as properties. ``` - ```javascript return f.form_name: //Returns an object with the inputs of a form (name, email, password, etc.). ``` - ```javascript return f.form_name.email: //Returns the value of the "email" input within the form ``` :::tip Note - In order for Wized to recognize forms, they must have the [Wized attribute](/start-here/getting-started/wized-attribute). - Form values ​​are only accessible after the form has been submitted; ::: ## i: Access to input fields - ```javascript return i : // Returns a list of all recognized inputs on the current page. ``` - ```javascript return i.input_name : // Returns the real-time value of the specified input. ``` :::tip Note In order for Wized to recognize inputs, they must have the [Wized attribute](/start-here/getting-started/wized-attribute), Refer to the [Input Fields section](/data-store/inputs) for more information. ::: ## n: Access to navigation - ```javascript return n.href : // Returns the current URL value. ``` - ```javascript return n.parameter : // Returns an object with all previously defined URL parameters. ``` - ```javascript return n.parameter.parameter_name : // Returns the specific value of a real-time parameter. ``` - ```javascript return n.path : // Returns the current navigation path. ``` ## r: Access to requests - ```javascript return r : // Returns a list of all requests and their values. ``` - ```javascript return r.request_name : // Returns the result, headers, and status of an executed request. ``` ## v: Access to variables - ```javascript return v : // Returns an array of all defined variables along with their values. ``` - ```javascript return v.variable_name : // Returns the specific value of the indicated variable. ``` ## t: Access to the Wized element object Provides access to the Wized Element object that defines the element that is associated with the function. This parameter is only available for element actions. # Available actions - **Perform a request:** Executes a specific request to an API. You can add an optional condition using the Function Editor to control when the request is executed. For example, you can chain multiple requests, executing one only if the previous one was successful. - **Set cookie:** Updates the value of an existing cookie or creates a new one. You can use the Function Editor to define the new value of the cookie and add optional conditions. - **Set variable:** Updates the value of an existing variable or creates a new one. You can use the Function Editor to define the new value of the variable and add optional conditions. - **Navigate to:** Redirects the user to another URL or route within your application. You can add an optional condition using the Function Editor to control when the redirection occurs. For example, you can redirect the user to a login page if they are not authenticated. - **Run function:** Executes a custom JavaScript code snippet. You can use this action to perform complex tasks or programmatically interact with elements on your page. For example: ## Use cases ### 1. Perform a request This action allows you to send a request to an external API in response to a global event. You can use it to fetch updated data, send information to a server, or perform any other operation that requires communicating with an external service. **Example:** - **Event:** Page Load Complete - **Action:** Perform a Request to get user profile data from an API. - **Configuration:** - **Request:** Select the API request you want to execute (e.g., getUserData). - **Condition (optional):** You can add a condition in the Function Editor to control when the request is executed. For example, only if the user is authenticated: ```javascript // Check if there is an authenticated user return c.loggedUser; ``` ### 2. Set cookie This action allows you to create a new cookie or update the value of an existing one. Cookies are useful for storing information in the user's browser, such as preferences, session data, or authentication tokens. **Example:** - **Event:** Request Completed (associated with a login request) - **Condition:** r.loginRequest.ok (True if the login was successful) - **Action:** Set Cookie to create a cookie named tokenUsuario with the value of the authentication token received from the API: ```javascript // Returns the authentication token from the login return r.loginRequest.data.token; ``` ### 3. Navigate to This action allows you to redirect the user to another page or URL within your application or to an external site. You can use it to create custom navigation flows or send the user to a specific page after completing an action. **Example:** - **Event:** Request Completed (associated with a user registration request) - **Condition:** r.registroUsuario.ok (True if the registration was successful) - **Action:** Navigate to redirect the user to the login page: ```javascript // Returns the URL of the login page return '/login'; ``` ### 4. Run function This action allows you to execute a custom JavaScript code snippet in response to a global event. It is useful for performing complex tasks, interacting with DOM elements, or implementing logic that cannot be achieved with predefined actions. **Example:** - **Event:** Page Load Start - **Action:** Run Function to initialize an external JavaScript library and configure it: ```javascript // Make sure to have imported the library in your Webflow project return initializeMyLibrary(); ``` ## Disabling actions To temporarily disable an action without deleting it, you can use the disable switch in the action's header. This feature allows you to pause specific functionalities and re-enable them later as needed. ![disable-actions](disable-functionality.png) # Global events **Global events** in Wized are system-wide event listeners that **react dynamically** to specified conditions, triggering predefined actions when those conditions are met. Unlike [element-based events](/elements/events), **Global events are not tied to a specific element or user interaction** they execute automatically whenever the defined condition evaluates as `true`. This allows you to create **reactive workflows**, where logic runs in the background based on application state, API responses, or custom triggers. --- ## How global events work Each **Global event** consists of two main components: 1. **Trigger** - Custom condition - Request finished - Attribute present - Page starts loading - Page finishes loading 2. **Conditional** - The validation rule that determines when the event is executed. - This condition is continuously evaluated in real time by Wized. 3. **Actions** - A set of tasks that will be executed **when the event is triggered**. - These actions can include executing requests, modifying variables, among others. --- ### **Example** Execute an API request when a user logs in **Trigger:** `Request finishes` **Condition:** The `ok` property of a login request becomes `true`. **Actions:** - Fetch user data from an API. - Store the user’s role in a variable. - Redirect to a dashboard page. --- ## Best Practices - **Use Global events for background automation** rather than user-triggered actions. - **Ensure conditions are specific** to prevent unintended executions. - **Leverage multiple actions** within a single event to streamline workflows. - **Test conditions manually** to verify they trigger as expected. # Event triggers Event triggers in Wized allow you to define **real-time event listeners** that execute specific actions when certain conditions are met. These triggers operate independently of user interaction and can be used to automate logic, update data dynamically, and manage application behavior efficiently. Each trigger can be accompanied by an **optional condition**, which determines whether the event should execute. If no condition is set, the event will always run when the trigger is activated. --- ## Available triggers ### **Custom condition** - Executes when a user-defined condition evaluates to `true`. - Conditions are created using the [function editor](/function-editor/) and can leverage: - Variables - Cookies - requests responses - Input values --- ### **Attribute Present** - Fires when an element with a specific [Wized attribute](/start-here/getting-started/wized-attribute) is detected on the current page. - Useful for triggering actions **based on dynamic elements** that load or appear conditionally. --- ### **Request Finished** - Executes **immediately after a request completes**, whether it succeeds or fails. You can set a conditional, so that this event is executed only when the validation is fulfilled and the request finishes. - Can be used to **handle API responses dynamically**, update UI components, or trigger subsequent requests. --- ### **Page Starts Loading** - Fires **as soon as the page starts rendering** in the browser. - Ideal for: - **Initializing variables** before any user interaction. - **Executing API requests early** to preload data. - **Displaying loading indicators** for better UX. --- ### **Page Finishes Loading** - triggers once **all page elements have fully loaded**. - Perfect for: - **Handling UI adjustments** that depend on the entire page being ready. - **Running animations** or interactive elements. - **Final validations** such as checking user authentication. --- ## `Page starts loading` Or `Page finishes loading` | Trigger | Best For | | ------------------------- | -------------------------------------------------------------------- | | **Page Starts Loading** | Initializing critical data, preloading APIs, showing loading states. | | **Page Finishes Loading** | Handling UI interactions, animations, final data validations. | Choosing the right trigger depends on **when** the action should take place for the best user experience. # Welcome to Wized documentation Welcome to the official **Wized documentation**! Here, you'll find everything you need to build powerful, dynamic web applications using Wized. Whether you're just starting or you're an experienced developer, this guide will help you unlock Wized’s full potential. ## Get Started with the community Wized is more than just a tool—it’s a growing ecosystem of builders, creators, and developers. Connect with the community, ask questions, and stay updated with the latest features and best practices. - 💬 **Join the community:** [Discord](https://discord.gg/nAxTsRYB) - 🎥 **Video tutorials & guides:** [YouTube Channel](https://www.youtube.com/@Wized) - 📩 **Support & help center:** [Submit a Ticket](https://www.wized.com/support) ## 🔥 Popular Resources If you're looking for specific guidance, here are some useful links to get you started: - 📖 **[Quick Start guide](/start-here/getting-started/)** – Learn the basics and set up your first project. - 🛠️ **[Integrations](/apps/)** – Connect Wized with external tools, APIs, and databases. - 🔄 **[API requests](/requests/)** – Learn how to work with APIs integrations. - 📚 **[Best practices](/workflows)** – Optimize performance and structure your data efficiently. - ⚡ **[Wized API](/javascript-api/)** – Dive into Wized API. Ready to start building? **Let’s go!** # JavaScript API Wized offers a JavaScript API to extend your web apps with custom logic, providing access to the following features: - The project configuration. - The Data Store. - The Wized Elements. - Global events. - Request helpers. Most of these functionalities can be accessed right from inside the [Function Editor](../function-editor/index.md), but in some cases you might want to use the JavaScript API directly from your own code. ## Initialize If you are writing custom code within Wized's [Function Editor](../function-editor/index.md), you have immediate access to the Wized object: ```js async (c, e, f, i, n, r, v) => { console.log(Wized.version); }; ``` Hovever, if you are writing code outside of the Function Editor, you need to ensure that the Wized API is loaded before executing your code. The following wrapper will ensure that your code is executed only after the Wized API has been initialized: ```js window.Wized = window.Wized || []; window.Wized.push((Wized) => { // Your code goes here }); ``` ## The `Wized` object ### `Wized.version` - **Type:** `string` Returns the current version of the Wized Embed library. This is useful when debugging your app. ```js window.Wized = window.Wized || []; window.Wized.push((Wized) => { console.log(Wized.version); }); ``` ### `Wized.config` - **Type:** `WizedConfig` Returns the project configuration that was loaded by Wized. This is useful when debugging your app. ```js window.Wized = window.Wized || []; window.Wized.push((Wized) => { console.log(Wized.config); }); ``` ### `Wized.data` - **Type:** `DataStore` Contains your project's Data Store, also known as your app's state. ```typescript type DataStore = { c: Record; f: Record>>; i: Record>; v: Record; r: Record; n: { href: string; path: string; parameter: Record; }; }; type WizedRequestData = { id: string; number: number; data: unknown; // The response data headers: Record; // The response headers isRequesting: boolean; hasRequested: boolean; statusText: string | null; status: number | null; ok: boolean | null; duration: number; }; ``` #### Reading values from the Data Store You can read any value from the Data Store by simply accessing the `Wized.data` object properties: ```js window.Wized = window.Wized || []; window.Wized.push((Wized) => { console.log(Wized.data.v.my_variable); console.log(Wized.data.c.my_cookie); }); ``` ::: info Note If you're writing code inside the [Function Editor](../function-editor/index.md) you don't need to use the `Wized.data` object, simply use the provided argumets directly. ::: #### Updating values in the Data Store You can update any value in the Data Store by simply assigning a new value to the `Wized.data` object properties or mutating them: ```js window.Wized = window.Wized || []; window.Wized.push((Wized) => { // Normal assignments Wized.data.v.my_variable = 'New value'; Wized.data.n.parameter.id = 1234; // Array updates Wized.data.v.items.push('New item'); Wized.data.v.items.sort(); Wized.data.v.items = [...Wized.data.v.items, 'Newer item']; // Nested objects Wized.data.f.my_form = { name: 'John', email: 'john@doe.com', }; }); ``` ::: info Note If you're writing code inside the [Function Editor](../function-editor/index.md) you don't need to use the `Wized.data` object, simply use the provided argumets directly. ::: Updates to: - Variables (`v.my_variable`): will trigger any reactivity associated to them. This applies to any other field in the Data Store too. - Cookies (`c.my_cookie`): will set the new cookie value to the browser. To remove cookies, just set the value to `null`. - Parameters (`n.parameter.my_parameter`): will set the new parameter value to the current URL. To remove parameters, just set the value to `null`. - Inputs (`i.my_input`): will set the new input value to the input field. Each field expects the correct value type: - Text inputs: `string` - Number and range inputs: `number` - Checkboxes: `boolean` - Checkbox groups: `Array` - Radio groups: `string` - Select dropdowns: `string` - Multi-select dropdowns: `Array` - Forms (`f.my_form`): any field of a form can be updated using the field name. The expected value types are the same as Inputs (`i`). - Update a single field: `Wized.data.f.my_form.name = "John"` - Update multiple fields: `Wized.data.f.my_form = { name: 'John', email: 'john@doe.com' };` - Requests (`r.my_request`): although it’s possible to update requests state using the API, it’s not recommended as it can create conflicts with the native Actions & Requests. ### `Wized.reactivity.watch()` Watches one or more reactive Data Store values and invokes a callback function when the sources change. Example: ```js window.Wized = window.Wized || []; window.Wized.push((Wized) => { Wized.reactivity.watch( () => Wized.data.v.my_variable, (newValue, oldValue) => { console.log(`my_variable changed from ${oldValue} to ${newValue}`); } ); }); ``` Example with multiple values: ```js window.Wized = window.Wized || []; window.Wized.push((Wized) => { Wized.reactivity.watch( [() => Wized.data.v.my_variable, () => Wized.data.v.my_other_variable], ([newVar, newOtherVar], [oldVar, oldOtherVar]) => { console.log(`my_variable changed from ${oldVar} to ${newVar}`); console.log(`my_other_variable changed from ${oldOtherVar} to ${newOtherVar}`); } ); }); ``` This function is provided by Vue's [@vue/reactivity](https://www.npmjs.com/package/@vue/reactivity) package, [the full documentation can be found here](https://vuejs.org/api/reactivity-core.html#watch). ### `Wized.reactivity.effect()` Runs a function immediately while reactively tracking any Data Store values and re-runs it whenever those values are changed. Example: ```js window.Wized = window.Wized || []; window.Wized.push((Wized) => { Wized.reactivity.effect(() => { console.log(Wized.data.v.my_variable); }); }); ``` This function is provided by Vue's [@vue/reactivity](https://www.npmjs.com/package/@vue/reactivity) package, [the full documentation can be found here](https://vuejs.org/api/reactivity-core.html#watcheffect). ### `Wized.requests.execute()` - **Type:** `(identifier: string) => Promise` The function expects an identifier of the request that can be either the Request ID or the Request name. Triggers a request and returns a Promise with the [WizedRequestData](#wizeddata). Example: ```js window.Wized = window.Wized || []; window.Wized.push(async (Wized) => { const result = await Wized.requests.execute('request_name'); console.log(result); }); ``` ### `Wized.requests.waitFor()` - **Type:** `(identifier: string) => Promise` The function expects an identifier of the request that can be either the Request ID or the Request name. Returns a Promise that resolves when the request has finished. As opposite to [Wized.requests.execute](#wizedrequestsexecute), this method does not execute the request, only awaits for it to finish. ```js window.Wized = window.Wized || []; window.Wized.push(async (Wized) => { const result = await Wized.requests.waitFor('request_name'); // This will not trigger a request execution console.log(result); }); ``` ### `Wized.requests.getClient()` - **Type:** `(identifier: string) => Promise` ::: warning Warning This is an advanced feature and should only be used if you know what you are doing. ::: The function expects an identifier that can be either a Request ID, a Request name, an App ID or an App name. Returns the client used to execute the request. This is useful when you need to interact with the SDK client directly via custom code. Currently only [Supabase](https://supabase.com/docs/reference/javascript/introduction) and [Firebase](https://firebase.google.com/docs/reference/js) clients are supported, and the returned object will be one of the following: ```typescript type WizedClientData = | { type: 'supabase'; version: string; // The version of the SDK, i.e. "2.39.7" client: SupabaseClient; // https://supabase.com/docs/reference/javascript/initializing } | { type: 'firebase'; version: string; // The version of the SDK, i.e. "10.8.1" app: FirebaseApp; // https://firebase.google.com/docs/reference/js/app.firebaseapp.md#firebaseapp_interface} auth: Auth; // https://firebase.google.com/docs/reference/js/auth.auth.md#auth_interface firestore: Firestore; // https://firebase.google.com/docs/reference/js/firestore_.firestore.md#firestore_class storage: FirebaseStorage; // https://firebase.google.com/docs/reference/js/storage.firebasestorage.md#firebasestorage_interface modules: { // Modules to interact with the client, dynamically imported from the `firebase` npm package app: Promise; auth: Promise; firestore: Promise; storage: Promise; }; }; ``` You can use this method to interact with the client like this: ```js window.Wized = window.Wized || []; window.Wized.push(async (Wized) => { const { version, client } = await Wized.requests.getClient('my_supabase_app'); // You should check the client version before using it, as the API might change between versions if (version.startsWith('2')) { const user = await client.auth.getUser(); } }); ``` Notice how in the example above we check the client version before using it. This is an important step because Wized may update the client version in the future, and the API might change between versions. ::: warning Important Wized reserves the right to update client versions without prior notice, it's the developer's responsibility to keep their code prepared for newer versions of the SDKs. ::: To interact with the Firestore client, you may want to access the modules included in [the firebase npm package](https://www.npmjs.com/package/firebase). You can do this via the `modules` object, which the `firebase/app`, `firebase/auth`, `firebase/firestore`, and `firebase/storage` modules. Each accessor is a promise that returns the npm module when resolved: ```js window.Wized = window.Wized || []; window.Wized.push(async (Wized) => { const { version, firestore, modules } = await Wized.requests.getClient('my_firebase_app'); // Check for the client version if (version !== '10') return; // Retrieve the Firestore module const { doc, getDoc } = await modules.firestore; // Use the Firestore methods const docRef = doc(firestore, 'todos', '1234'); const docSnap = await getDoc(docRef); const todo = docSnap.data(); }); ``` ### `Wized.elements.get()` - **Type:** `(name: string) => WizedElement` Returns a [WizedElement](#the-wizedelement-object) instance by its name. If there are multiple elements with the same name, it will just return the first one. ```js window.Wized = window.Wized || []; window.Wized.push((Wized) => { const element = Wized.elements.get('element_name'); }); ``` ### `Wized.elements.getAll()` - **Type:** `(name?: string) => WizedElement[]` Returns an array of all the app's [WizedElement](#the-wizedelement-object) instances. If a name is provided, it will return all the elements with that name. ```js window.Wized = window.Wized || []; window.Wized.push((Wized) => { const elements = Wized.elements.getAll(); // Returns all the elements const elementsWithName = Wized.elements.getAll('element_name'); // Returns all the elements with the name "element_name" }); ``` ### `Wized.elements.update()` - **Type:** `() => WizedElement[]` Forces Wized to rescan the current page to find any newly added elements. You can use this method if you programatically add DOM nodes to the page after Wized has initialized. Returns an array of all the new [WizedElement](#the-wizedelement-object) instances, if any. ```js window.Wized = window.Wized || []; window.Wized.push((Wized) => { // Example: clone an element const element = Wized.elements.get('element_name'); const clone = element.node.cloneNode(true); document.body.appendChild(clone); // Rescan to initialize the new element const newElements = Wized.elements.update(); console.log(newElements); }); ``` ### `Wized.on()` - **Type:** `(eventName: string, listener: (event: Event) => void) => void` Listens for global events of the app. The following events are available: #### `Wized.on('requeststart', listener)` This event is fired when a request is triggered. The listener callback receives an object with the request name and ID. ```js window.Wized = window.Wized || []; window.Wized.push((Wized) => { Wized.on('requeststart', (result) => { console.log(`Request ${result.name} was triggered`); }); }); ``` #### `Wized.on('requestend', listener)` This event is fired when a request execution finalizes. The listener callback receives a [WizedRequestData](#wizeddata) object. ```js window.Wized = window.Wized || []; window.Wized.push((Wized) => { Wized.on('requestend', (result) => { console.log(`Request ${result.name} finalized executing after ${result.duration}ms`); }); }); ``` ## The `WizedElement` object For each element that is defined with a `wized = "element_name"` HTML attribute in Webflow, Wized creates a `WizedElement` instance that is used for several purposes: - Store element-specific state. - Store the element's actions and cleanups. - Store the element's node or anchor (when not rendered). - Store the element's clones when applying a [Render List](../elements/configuration-types/single-use/render-list) action. - Store the element's child tree. ### `WizedElement.name` - **Type:** `string` Returns the element name. ### `WizedElement.rendered` - **Type:** `boolean` Returns `true` if the element is currently rendered on the page, `false` otherwise. The rendered state is controlled via the [Set Visibility](../elements/configuration-types/single-use/set-visibility) action. ### `WizedElement.node` - **Type:** [Element](https://developer.mozilla.org/en-US/docs/Web/API/Element) Returns the element's DOM node. This is useful when you need to interact with it directly instead of using Wized's actions. The node is only present in the DOM when the element is [rendered](#wizedelementrendered). ### `WizedElement.anchor` - **Type:** [Comment](https://developer.mozilla.org/en-US/docs/Web/API/Comment) The element's anchor is a placeholder comment that is put in place when the element is not rendered. This is useful when you need to interact with it directly instead of using Wized's actions. The anchor is only present in the DOM when the element is not [rendered](#wizedelementrendered). ### `WizedElement.parent` - **Type:** `WizedElement | undefined` Returns the element's parent [WizedElement](#the-wizedelement-object) instance, if any. ### `WizedElement.children` - **Type:** `WizedElement[]` Returns an array of the element's child [WizedElement](#the-wizedelement-object) instances. ### `WizedElement.clones` - **Type:** `WizedElement[]` Returns an array of the element's clones. Clones are created when applying a [Render List](../elements/configuration-types/single-use/render-list) action. ### `WizedElement.data` - **Type:** `Record` A reactive object used to store element-specific data. This object is shared across all the element's tree (parents and children). ### `WizedElement.on()` - **Type:** `(eventName: string, listener: (event: Event) => void) => void` Adds a lifecycle event listener to the element. The listener will be removed when the element is destroyed. ```js window.Wized = window.Wized || []; window.Wized.push((Wized) => { const element = Wized.elements.get('element_name'); element.on('attribute', (event) => { console.log(`Attribute ${event.key} was updated to ${event.value}`); }); }); ``` The following events are available: #### `WizedElement.on("attribute", listener)` This event is fired when the element's attributes are updated via a [Set HTML Attribute](../elements/configuration-types/multi-use/set-html-attribute.md) action. The listener callback receives the following event object: - `event.key`: The HTML Attribute key. - `event.value`: The new value. #### `WizedElement.on('class', listener)` This event is fired when the element's CSS classes are updated via a [Set Class](../elements/configuration-types/multi-use/set-class) action. The listener callback receives the following event object: - `event.className`: The CSS class name. - `event.valid`: Defines if the class was added or removed. #### `WizedElement.on('list', listener)` This event is fired when the element's clones are updated via a [Render List](../elements/configuration-types/single-use/render-list) action. The listener callback receives the following event object: - `event.addedClones`: The added element clones. - `event.updatedClones`: The clones that were kept in the DOM. - `event.removedClones`: The clones that were destroyed. #### `WizedElement.on('parameter', listener)` This event is fired when the element's URL parameters are updated via a [Set URL Parameter](/elements/configuration-types/multi-use/url-parameter) action. The listener callback receives the following event object: - `event.name`: The URL parameter name. - `event.value`: The new value. #### `WizedElement.on('style', listener)` This event is fired when the element's inline styles are updated via a [Set Style](../elements/configuration-types/multi-use/set-style.md) action. The listener callback receives the following event object: - `event.style`: The style name. - `event.value`: The new value. #### `WizedElement.on('text', listener)` This event is fired when the element's text is updated via a [Set Text](../elements/configuration-types/single-use/set-text.md) action. The listener callback receives the following event object: - `event.type`: The type of update that was made (text, html or markdown). - `event.value`: The new value. #### `WizedElement.on('value', listener)` This event is fired when the element's input value is updated via a [Set Input Value](../elements/configuration-types/single-use/set-input-value) action. The listener callback receives the following event object: - `event.value`: The new value. #### `WizedElement.on('visibility', listener)` This event is fired when the element's render state is updated via a [Set Visibility](../elements/configuration-types/single-use/set-visibility) action. The listener callback receives the following event object: - `event.displayed`: Defines if the element was added or removed from the DOM. > [!NOTE] > To use this method, you will need to enable authentication in the App configuration # Airtable Requests ## What is an Airtable Request? An Airtable request is a way to integrate your Application with Airtable. You can retrieve data, create new records, update existing ones, or delete information with Airtable as your backend database. You can use Airtable to just fetch data without any authentication like in public blogs, or you can use authentication build by Wized so users can create account, sign in, read and write data based on permission setup in Wized configurator. To create airtable requests you will need to first create an Airtable Wized App. ## How to Create Airtable App ### 1. Go to My Apps Begin by going to the 'My Apps' panel in Wized. 1. Click the `+` button at the top of the panel. 2. Add a name for your app for later reference, i.e. `Airtable App`. 3. Pick the `Airtable` option. ![Adding an Airtable App to my apps](my-apps.png) 4. Connect Airtable using OAuth and select bases you want to use with this app 5. Click "Add base" and select Airtable Base 6. Click "Grant access" and wait for the authorization ![Connect Airtable Oauth Popup](wized-airtable-connect-popup.png) ### 2. Configure your request #### Create a new request, and add basic info - Name your request i.e. `get_blog_posts` - Add your request to a folder (optional) - Select your Airtable App from the dropdown ![Adding basic info to our request](airtable-request.png) #### Select method You will need to select one of the methods for a specific functionality - [Create user](./methods/authentication/create-user/index.md) Create a user with specified email and password and store in the table you selected in app configuration - [Login user](./methods/authentication/login-user/index.md): Login a user with email and password - [Load user](./methods/authentication/load-user/index.md): Load authenticated user - [Logout user](./methods/authentication/logout-user/index.md): Sign out currently authenticated user - [Delete user](./methods/authentication/delete-user/index.md): Delete currently authenticated user - [Request password reset](./methods/authentication/request-password-reset/index.md): Request password reset - [Password reset](./methods/authentication/password-reset/index.md) Reset password with new password - [Get item](./methods/data/get-item/index.md): Get Airtable Record item - [Get list items](./methods/data/get-list-items/index.md): Get Airtable Record list of items - [Create item](./methods/data/create-item/index.md): Create Airtable Record - [Update item](./methods/data/update-item/index.md) Update Airtable Record - [Delete item](./methods/data/delete-item/index.md): Delete Airtable Record ### 3. User authentication If you want to have an authentication system on your app, you just need to check "Enable authentication" in the app configuration ![Enable authentication](enable-user-authentication.png) Select Base from which you want to store and retrieve users Select table from which you want to store and retrieve users In the selected table you will need to have two fields, email, email verified and password Select email, email verified and password fields and you are ready to go. Go to the Requests panel and start configuring your request. ## Create user method With "Create User" method, you can implement sign-up functionality in your application. Users will be saved in the Base and table you selected in the [App configuration](../../../index#how-to-create-airtable-app). - All passwords will be encrypted! ### Parameters - Email: This is a required [function field](../../../../../function-editor/index.md) where you can return the user's email. - Password: This is a required function field where you can input the user's password. - Page: This is an optional function field where you can input the URL of the page to which you want to redirect the user after successful sign-up. - Auto Login: This is a checkbox field that lets Wized know if you want to automatically sign in the new user or not. ![User Create Method](user-create-method.png) ## Delete user method With "Delete User" method, you can implement delete user functionality in your application. User will be deleted from the Base and table you selected in the App configuration. ![User delete Method](delete-user.png) ## Load user method With "Load User" method, you can fetch current authenticated user! This usually need to be done when app loads the first time, then you can save that on app state! Users will be retrieved from the Base and table you selected in the App configuration. ### Parameters - Page: Page url to redirect after loading the user. ![User Load Method](load-user-method.png) ## Login user method With "Login User" method, you can implement sign-in functionality in your application. Users will be retrieved from the Base and table you selected in the App configuration. ### Parameters - Email: This is a required [function field](/function-editor/) where you can input the user's email. - Password: This is a required function field where you can input the user's password. - Page: This is an optional function field where you can return the URL of the page to which you want to redirect the user after successful login. ![User Login Method](login-user-method.png) ## Login with magic link method With "Login with magic link" method, you can implement passwordless sign in functionality in your application. You will first need to use ["Send magic link"](../send-magic-link/index) method to send the link to the email. This method will get access token from the link that is build from "Send magic link" method and will login user! ### Parameters - Redirect url: This is an optional [function field](../../../../../function-editor/index.md) where you can redirect user after successful sign in! ![Login with magic link method](login-with-magic-link.png) ## Logout user method With "Logout User" method, you can implement logout functionality in your application. This will clear the current user data from the application state and you can redirect user with page param to the page you want! ### Parameters - Page: Page to redirect after logout! ![User Logout Method](logout-user-method.png) ## Password reset method With "Password reset" method, you can implement password reset functionality in your application. After user click on the link from email that is sent from "Request password reset" method, user will need to be redirected in this page and query params will be added to the page. This need to be called after user will write the new password in the input fields in the page. ### Parameters - New Password: This is a required [function field](/function-editor/) where you can return user's submitted new password. ![Password reset method](password-reset-method.png) ## Request password reset method With "Request password reset" method, you can implement password reset functionality in your application. An email with reset link will be sent to the user email that is returned from email param function. ### Parameters - Email: This is a required [function field](/function-editor/) where you can return user's email. - Redirect url: This is a required function field where you can return the page url in which user will input the new password. ![Request password reset method](request-password-reset-method.png) ## Send email verification link method With "Send email verification link" method, you can implement email verification in your application. This method will send a verify link to the user email and after user go to that link, you will need to call "Verify email" method to verify the email. ### Parameters - Email: This is a required [function field](/function-editor/) where you can return user's submitted email. - Redirect url: This is a required [function field](/function-editor/) where you can return the url of the page in which you plan to redirect user from email. ![Send email verification link method](send-email-verification-link.png) ## Send magic link method With "Send magic link" method, you can implement passwordless sign in functionality in your application. This method will send a login link to the user email and after user go to that link, you will need to use the "Login with magic link" method to login user to your application. ### Parameters - Email: This is a required [function field](/function-editor/) where you can return user's submitted email. - Redirect url: This is a required [function field](/function-editor/) where you can return the url of the page in which you plan to redirect user from email. ![Send magic link method](send-magic-link-method.png) ## Verify email method With "Verify email" method, you can implement last step of email verification functionality in your application. This method will get access token from the link that is build from "Send email verification link" method and will verify the email! ### Parameters - Redirect url: This is an optional [function field](/function-editor/) where you can redirect user after successful email verification! ![Verify email method](verify-email-method.png) ## Create item method With "Create item" method, you can create a record from the specified Base and Table. ### Main Parameters - Base: This is a required dropdown field where you can select the base you want to create the record into. - Table: This is a required dropdown field where you can select the table you want to get the record into. ![Create item method](create-item-method.png) ### Permissions You can select who can create record You can select from: - Allow Any: Any user can create a record - Authenticated: Any authenticated user can create record - Owner: Authenticated user can create the record, and user id will be stored into record. If you select this option, you will need to select also the field in which you will store user id ![Owner permissions](../../../owner-permissions.png) ### Fields Airtable fields will be listed as function fields, in which you will need to specify for each one what value will be returned. ## Delete item method With "Delete item" method, you can delete an existing record from the specified Base and Table. ### Main Parameters - Base: This is a required dropdown field where you can select the base you want to delete existing record from. - Table: This is a required dropdown field where you can select the table you want to delete existing record from. - Record ID: This is an required function field where you can return the record id that you want to delete. ![Delete item method](delete-item-method.png) ### Permissions You can select who can delete record You can select from: - Allow Any: Any user can delete the record - Authenticated: Any authenticated user can delete the record - Owner: Authenticated user can delete the record if the user id field value will match with authenticated user. If you select this option, you will need to select also the field in which you will store user id > [!NOTE] > In most cases you need to select Owner here, so only users that created the record can also delete it. ![Owner permissions](../../../owner-permissions.png) ## Get item method With "Get item" method, you can retrieve a single airtable record from the specified Base and Table. ### Main Parameters - Base: This is a required dropdown field where you can select the base you want to get the record from. - Table: This is a required dropdown field where you can select the table you want to get the record from. - Record ID: This is an required function field where you can return the record id that you want to retrieve. - Limit fields to: This is an optional multi select dropdown field in which you can select fields that you want to retrieve. ![Get item method](get-item-method.png) ### Permissions You can select who can retrieve this record You can select from - Allow Any: Any user can retrieve this record - Authenticated: Any authenticated user can retrieve this record - Owner: Only the user that created this record can retrieve it - If you select Owner, you will need to select also the field in which the user id is stored ![Owner permissions](../../../owner-permissions.png) ## Get list items method With "Get list items" method, you can retrieve and filter multiple records from the specified Base and Table. ### Main Parameters - Base: This is a required dropdown field where you can select the base you want to get items from - Table: This is a required dropdown field where you can select the table you want to get items from - Limit fields to: This is an optional multi select dropdown field in which you can select fields that you want to retrieve. - View: This is an optional required dropdown field where you can select the view you want to get items from ![Get list items method](get-list-items.png) ### Permissions You can select who can retrieve the data You can select from: - Allow Any: Any user can retrieve the data - Authenticated: Any authenticated user can retrieve the data - Owner: Only records that user field value will match with currently authenticated user id will be retrieved - If you select Owner, you will need to select also the field in the user id is stored > [!NOTE] > In most cases you need to select Owner here, so only users that created the records can also retrieve them. ![Owner permissions](../../../owner-permissions.png) ### Filter Parameters You can add multiple filters and each filter will need to have params: - Include record if: This is a required dropdown field in which you will need to select table field to apply filter to - Condition: This is a required dropdown filed with values Equals, Does not equal, Includes, Does not include - Value: This is a required function field, in which you will need to select the value to test with condition ![Filtering](get-list-items-filtering.png) ### Filtering Records Based on Reference Fields To filter records based on a reference table field, you need to create a lookup field for that table and select the field you want to filter with. _Figure 1: Example of a reference field_ ![Reference Field](get-list-reference-fields-filtering.png) _Figure 2: Configuration of a reference field for filtering_ ![Reference Field Configuration](get-list-reference-fields-filtering-config.png) ### Pagination Parameters You can paginate airtable records result with following params: - Page size: The number of records returned in each request. Must be less than or equal to 100. Default is 100. - Offset: To fetch the next page of records, include offset from the previous request in the next request parameters. - Max records: The maximum total number of records that will be returned in your requests. If this value is larger than pageSize (which is 100 by default), you may have to load multiple pages to reach this total. ![Pagination](get-list-pagination.png) ### Sort Parameters You can add multiple sort conditions and each condition will need to have params: - Sort by: This is a required dropdown field in which you will need to select table field to apply sorting - Order: This is a required dropdown filed with values Ascending, Descending ![Sorting](get-list-sorting.png) ## Update item method With "Update item" method, you can update an existing record from the specified Base and Table. ### Main Parameters - Base: This is a required dropdown field where you can select the base you want to update existing record. - Table: This is a required dropdown field where you can select the table you want to update existing record. - Record ID: This is an required function field where you can return the record id that you want to update. ![Create item method](update-item-method.png) ### Permissions You can select who can update record You can select from: - Allow Any: Any user can update a record - Authenticated: Any authenticated user can update record - Owner: Authenticated user can update the record if the user id field value will match with authenticated user If you select this option, you will need to select also the field in which you will store user id > [!NOTE] > In most cases you need to select Owner here, so only users that created the record can also update it. ![Owner permissions](../../../owner-permissions.png) ### Fields Airtable fields will be listed as function fields, in which you will need to specify for each one what value will be returned. # Creating a request **Requests** allow your project to communicate with external web services through APIs. Before creating a request, you need to have an [app](/apps/) set up. An app acts as an integration and can be either a **native integration** (prebuilt by Wized) or a **REST integration** (fully customizable). ## Creating requests for native apps If you are using a **native integration**, Wized provides predefined methods that simplify request creation. Currently, Wized offers native integrations with `Supabase, Memberstack, Firebase, and Airtable`. These services primarily handle databases and authentication. ### Steps to create a native request 1. Navigate to the left sidebar and click on `Requests`. This opens the **requests panel**. 2. If you have existing requests, they will be listed here. To create a new one, click on the **`+`** icon in the top-right corner. 3. In the right panel, configure the request by: - Naming the request. - Selecting the **app**. ![name-app-overview](name-app-overview.png) 4. Once the app is selected, configure the request using a series of dropdown menus: - Choose the **method** from the available options. The available methods depend on the selected integration and may include actions like: `Get List Items`, `Get Item`, `Login`, `Create Item`, `Sign In`, `Update Profile`, `Get User`. ![native-request-methods](native-request-methods.png) - Depending on the selected method, a set of inputs will appear. For example :::tip Note To see all the available methods, go to the documentation of the native integration of your choice ::: **Example** if you are configuring a **login** request, you will need to provide the **email** and **password** fields. ![login_request_example](login_request_example.png) ::: info Note Wized does not handle authentication itself; it simply facilitates the necessary API calls based on the chosen method. ::: --- ## Creating REST requests If you need to interact with a third-party service that is not covered by Wized’s native integrations, you can create a **REST API request**. ### Steps to create a REST request 1. Navigate to the left sidebar and click on `Requests`. 2. Click on the **`+`** icon to create a new request. 3. In the right panel, configure the request by: - Naming the request. - Selecting **REST** as the app. 4. Once REST is selected, manually configure the request: - Choose the **HTTP method** (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`). - Set the **endpoint URL** (only the relative path, as the base URL was already configured when creating the app). - Define **parameters, headers, and body** using key-value pairs: - The **key** is a fixed text string (e.g., `Authorization`, `Content-Type`, `userId`). - The **value** can be set using Wized’s [function editor](/function-editor/), allowing you to use real-time data from: `Cookies, Variables, Request responses, URL parameters, among others` ::: info Note To properly configure REST requests, refer to the API documentation of the service you want to integrate. There, you'll find details about endpoints, parameters, headers, and the required request body. ::: ## Next steps Now that you have created your request, the next step is to **trigger** and **use** the request inside your project. You can execute requests based on [user interactions](/elements/events) or [global events](/global-events/). # Confirm Password Reset The `Confirm password reset` method is used to set a new password for a user existing in your Firebase app. It requires an `OOB Code` that is obtained by first [sending a password reset email to the user](../send-password-reset/index.md). To make a request to confirm a password reset, follow these steps: 1. Open the request panel and click on the `+` button to add a new request. 2. Fill in an appropriate name for the request and select the Firebase app to be used for the request. Then, under the method, choose `Confirm password reset`. 3. Provide the new `Password` and the `OOB Code` received from the [Send password reset email](../send-password-reset/index.md), usually through the page query parameters. ![Confirm password reset Firebase](confirm_password_reset_1.png) # Create Item The `Create Item` method enables you to add a document to a collection in your Firebase Cloud Firestore. To create a request to add a document to a collection, follow the steps below: 1. Open the request panel and click on the `+` button to add a new request. 2. Fill in an appropriate name for the request and select the Firebase app to be used for the request. Then, under the method, choose `Create Item`. ![Create Item Firebase](create_item_1.png) 3. Under the `Path`, fill in the full path to the collection in your Cloud Firestore database. ![Create Item Firebase](create_item_2.png) 4. Add the data of the new document to be added in key-value pairs. ![Create Item Firebase](create_item_3.png) # Delete Item The `Delete Item` method allows you to delete a specific document or an entire collection from your Cloud Firestore. To create a request to delete a document or collection, follow the steps below: 1. Open the request panel and click on the `+` button to add a new request. 2. Provide an appropriate name for the request and select the Firebase app to be used for the request. Then, choose `Delete Item` as the method. 3. In the `Path` field, enter the full path to the document or collection in your Cloud Firestore database. ![Delete Item Firebase](delete_item_1.png) # Get File URL The `Get File URL` method is used to obtain the full public-facing URL paths to your file in Cloud Storage in Firebase. To make a request to get the file URL, follow these steps: 1. First, ensure you have Cloud Storage set up on your Firebase app. :::info NOTE The clip starts with the project in test mode - this isn't secure. You'll need to update the Firebase rules. ::: 2. Make sure that the Storage Bucket is defined in your [Firebase App integration](../index.md#adding-an-app-to-your-project-in-the-firebase-console). 3. Open the request panel and click on the `+` button to add a new request. 4. Fill in an appropriate name for the request and select the Supabase app to be used for the request. Then, under the method, choose `Get File URL`. 5. Scroll down to fill in the bucket name and storage path of the file. You can then choose whether to download it or just display it. ![Get File URL Firebase](get_file_url_1.png) # Get Item The `Get Item` method allows you to fetch a specific document from your Cloud Firestore. To create a request to get an item, follow the steps below: 1. Open the request panel and click on the `+` button to add a new request. 2. Provide an appropriate name for the request and select the Firebase app to be used for the request. Then, choose `Get Item` as the method. 3. Fill in the full path to the document in your Cloud Firestore database under the `Path` field. ![Get Item Firebase](get_item_1.png) ::: info NOTE In most cases, the Get Item request requires the document ID at the end of the path. ::: # Get items list The `Get items list` method allows you to fetch a collection from your Cloud Firestore. To create a request to get a collection, follow the steps below: 1. Open the request panel and click on the `+` button to add a new request. 2. Provide an appropriate name for the request and select the Firebase app to be used for the request. Then, choose `Get items list` as the method. ![Get Item list Firebase](get_list_1.png) 3. Fill in the full path to the collection in your Cloud Firestore database under the `Path` field. ![Get Item list Firebase](get_list_2.png) The `Limit items` field is optional, but for much larger collections, we do advise using it. The `Subscribe realtime` checkbox allows you to listen to your data and receive real-time updates. 4. (Optional) If you want to filter, you can provide a field path to filter by, as well as the criteria to filter by. In the screenshot below, we are filtering by the `name` field path, and we only want those matching the value `John Doe` to be returned. ![Get Item list Firebase](get_list_3.png) 5. (Optional) If you want to sort, you can provide a field path to sort by, as well as the direction to sort by. In the screenshot below, we are sorting by the `name` field path in ascending order. ![Get Item list Firebase](get_list_4.png) 6. (Optional) To paginate your results, you can use one of the following methods: a. Start After Use this method to begin pagination after a specific value. ![Get Item list start after Firebase](get_list_pagination_start_after.png) b. Start At Use this method to begin pagination at a specific value. ![Get Item list start after Firebase](get_list_pagination_start_at.png) c. Multiple Fields Pagination To paginate with multiple fields, specify sort by for the fields you want, and define the starting point as a list. ![Get Item list multiple fields](get_list_pagination_multiple.png) # Get User The `Get User` method is used to retrieve the details of the currently logged-in user using Firebase. To make a request to get a user, follow these steps: 1. Open the request panel and click on the `+` button to add a new request. 2. Fill in an appropriate name for the request and select the Firebase app to be used for the request. Then, under the method, choose `Get user`. ![Get User Firebase](get_user_1.png) # Firebase Requests Wized has a native Firebase integration, which makes it easy to make requests to your Firebase app to perform CRUD operations on Cloud Firestore. Firebase is a popular Backend-as-a-Service (BaaS) that provides a real-time database. It is a NoSQL database that stores data in JSON-like documents. ## How to get started? ### Creating a project in the Firebase console To start using Firebase, first, you need to create a project in [the Firebase console](https://console.firebase.google.com/). You'll see a screen similar to the one below. ![Firebase console](./introduction_2.png) Click on the `Add Project` button and follow the on-screen prompts. Not much customization is needed for this sample app, so just clicking on continue for all steps with the default settings will be okay. ### Adding an app to your project in the Firebase console After successfully creating a project, you'll be presented with this screen where we should add our app. ![Firebase console successful project creation](./introduction_5.png) Since what we are building is a web app, we will click on the `` button, which will give us a set of credentials to use in Wized. You'll then give it an appropriate name, and on the step of adding the Firebase SDK, we will choose to do so via script tags. Copy the `firebaseConfig` values for use in setting up the Firebase app in Wized. ![Firebase console config](./introduction_4.png) ### Setting up Firebase in the Wized configurator In the Wized configurator, go to `My Apps`, then click on the `+` button to add an app. Give the app an appropriate name, and under the `App` option, choose `Firebase`. Next, transfer the data from the Firebase config copied earlier onto Wized. If you lost access to the Firebase config, you can always [find it in the Firebase project settings](https://support.google.com/firebase/answer/7015592). The final result will be as below: ![Firebase console](./introduction_3.png) ### Creating Cloud Firestore After creating an app, we'll need to add a database to store our data, and that is where Cloud Firestore comes into play. Check out an example below of creating the Cloud Firestore and manually adding a document to it. ### Securing your database Firebase implements security rules to protect your data. It is very important that you take the time to understand how to write these rules to ensure your data is secure. Otherwise, anyone can potentially read or write to your database. Check out the [Firebase documentation](https://firebase.google.com/docs/firestore/security/get-started) for more information. # Send Password Reset The `Send password reset` method is used to send an email to an existing user in Firebase for password resetting. To make a request to send a password reset email, follow these steps: 1. Open the request panel and click on the `+` button to add a new request. 2. Fill in an appropriate name for the request and select the Firebase app to be used for the request. Then, under the method, choose `Send password reset`. 3. Under the Email menu, fill in the email (or use an [input field](../../../data-store/inputs.md) or [form field](../../../data-store/forms.md)). ![Send password reset Firebase](send_password_reset_1.png) # Send Verification Email method The `Send verification email` method is used to send an email to signed in user for email verification. To make a request to send an email verification, follow these steps: 1. Open the request panel and click on the `+` button to add a new request. 2. Fill in an appropriate name for the request and select the Firebase app to be used for the request. Then, under the method, choose `Send verification email`. ![Send verification email](send-verification-email.png) # Set Item The `Set Item` method works similarly to the [Create Item](../create-item/index.md) method but performs upserting instead. If the document already exists, the `Set Item` method will overwrite the existing document with the new data provided or merge the new data with the existing data in the document, depending on whether the `Merge Fields` option is active. If the document does not exist, the `Set Item` method will create a new document with the provided data. ## Example Request 1. Open the request panel and click on the `+` button to add a new request. 2. Fill in an appropriate name for the request and select the Firebase app to be used for the request. Then, under the method, choose `Set Item`. ![Set Item Firebase](set_item_1.png) 3. Under the `Path`, fill in the full path to the document in your Cloud Firestore database. ![Set Item Firebase](set_item_4.png) 4. Fill in the key-value pairs with the data to be set. ![Set Item Firebase](set_item_3.png) # Sign in with email and password The `Sign in with password` method is used to authenticate an existing user to your application using the traditional format of providing an email and a password. To make a request to sign in a user using an email and password, follow these steps: 1. Open the request panel and click on the `+` button to add a new request. 2. Fill in an appropriate name for the request and select the Supabase app to be used for the request. Then, under the method, choose `Sign in (email + password)`. ![Sign in Firebase](sign_in_1.png) 3. Scroll downwards under the Email menu, fill in the email (or use an [input field](../../../data-store/inputs.md) or [form field](../../../data-store/forms.md)), and then fill in the password. ![Sign in Firebase](sign_in_2.png) # Sign in with OAuth provider The `Sign in with provider` method is used to authenticate a user to your site using a widely used third-party application providing OAuth. To make a request to authenticate a user using OAuth, follow these steps: 1. Open the request panel and click on the `+` button to add a new request. 2. Fill in an appropriate name for the request and select the Supabase app to be used for the request. Then, under the method, choose `Sign in with OAuth`. ![Sign in with OAuth Firebase](sign_in_1.png) 3. Scroll downwards to select the provider and add a redirect URL. ![Sign in with OAuth Firebase](sign_in_2.png) 4. Add the scopes required for your app. ![Sign in with OAuth Firebase](sign_in_3.png) :::info NOTE **Scopes** vary widely based on the provider used, and each provider has a sample of scopes on their respective documentation. An example is Facebook's scopes listed here: [https://developers.facebook.com/docs/permissions](https://developers.facebook.com/docs/permissions) ::: # Sign Out The `Sign Out` method is used to log out an authenticated user using Firebase. To make a request to sign out a user, follow these steps: 1. Open the request panel and click on the `+` button to add a new request. 2. Fill in an appropriate name for the request and select the Firebase app to be used for the request. Then, under the method, choose `Sign Out`. 3. Under the Email menu, fill in the email (or use an [input field](../../../data-store/inputs.md) or [form field](../../../data-store/forms.md)). ![Sign Out Firebase](sign_out_1.png) # Sign up with email and password The `Sign up(email + password)` method is used to add a new user to your application using the traditional format of providing an email and a password. To make a request to sign up a user using an email and password, follow these steps: 1. Open the request panel and click on the `+` button to add a new request. 2. Fill in an appropriate name for the request and select the Supabase app to be used for the request. Then, under the method, choose `Sign up(email + password)`. ![Sign up Firebase](sign_up_1.png) 3. Scroll downwards under the Email menu, fill in the email (or use an [input field](../../../data-store/inputs.md) or [form field](../../../data-store/forms.md)), then fill in the password. ![Sign up Firebase](sign_up_2.png) # Unsubscribe Real-Time The `Unsubscribe realtime` method lets you stop listening for live changes on your documents from earlier subscribed requests. To create a request to unsubscribe from realtime updates, follow the steps below: 1. Open the request panel and click on the `+` button to add a new request. 2. Fill in an appropriate name for the request and select the Firebase app to be used for the request. Then, under the method, choose `Unsubscribe realtime`. 3. Under the `Requests`, choose the request(s) to stop the realtime events from. ![Unsubscribe realtime Firebase](unsubscribe_realtime_1.png) # Update Email The `Update email` method is used to change the email of a user existing in Firebase. To make a request to update a user's email, follow these steps: 1. Open the request panel and click on the `+` button to add a new request. 2. Fill in an appropriate name for the request and select the Firebase app to be used for the request. Then, under the method, choose `Update email`. 3. Under the Email menu, fill in the email (or use an [input field](../../../data-store/inputs.md) or [form field](../../../data-store/forms.md)). ![Update email Firebase](update_email_1.png) # Update Item The `Update item` method enables you to change the details of a document in your Firebase Cloud Firestore. To create a request to update a document, follow the steps below: 1. Open the request panel and click on the `+` button to add a new request. 2. Fill in an appropriate name for the request and select the Firebase app to be used for the request. Then, under the method, choose `Update item`. ![Update item Firebase](update_item_1.png) 3. Under the `Path`, fill in the full path to the document in your Cloud Firestore database. ![Update item Firebase](update_item_2.png) :::info NOTE: Almost all of the time, the update item request needs the document ID at the tail end of the path. ::: 4. Fill in the key-value pairs with the data to be changed. ![Update item Firebase](update_item_3.png) # Update Profile The `Update profile` method is used to change the user's profile information in Firebase like the display name and photo URL. To make a request to update a user's profile, follow these steps: 1. Open the request panel and click on the `+` button to add a new request. 2. Fill in an appropriate name for the request and select the Firebase app to be used for the request. Then, under the method, choose `Update profile`. 3. Add the new `Display Name` or `Photo URL` for the user. # Upload File The `Upload file` method is used to upload files to your Firebase Cloud Storage. 1. First, ensure you have cloud storage added to your Firebase app. ::: info NOTE The clip starts with the project in test mode - this isn't secure. You'll need to update the Firebase rules. ::: 2. Make sure that the Storage Bucket is defined in your [Firebase App integration](../index.md#adding-an-app-to-your-project-in-the-firebase-console). 3. Open the request panel and click on the `+` button to add a new request. 4. Fill in an appropriate name for the request and select the Firebase app to be used for the request. Then, under the method, choose `Upload file`. 5. Scroll down to fill in the storage path of the file. Use an [input field](../../../data-store/inputs.md) or [form field](../../../data-store/forms.md) to choose the file to be uploaded. ![Upload file Firebase](upload_file_2.png) # Verify Email method The `Verify email` method is used to verify a user's email address in your Firebase app. It requires an `OOB Code` that is obtained by first [sending a verification email to the user](../send-verification-email/index.md). To make a request to verify an email, follow these steps: 1. Open the request panel and click on the `+` button to add a new request. 2. Fill in an appropriate name for the request and select the Firebase app to be used for the request. Then, under the method, choose `Verify email`. 3. Provide the `OOB Code` received from the [Send verification email](../send-verification-email/index.md), usually through the page query parameters. ![Verify email Firebase](verify-email.png) # Handling API errors When making API requests in Wized, errors can occur for various reasons. These errors generally fall into two categories: 1. **The request was not sent** – The request never reached the API server. 2. **The request was sent but returned an error** – The API responded with an error message. Understanding the cause of these errors will help you diagnose and fix them efficiently. --- ## When the request cannot be sent If the request is not sent, it means it never reached the API server. This can happen due to: - **Incorrect configuration in Wized** Double-check the request configuration in the **Requests panel**. Ensure the endpoint URL, HTTP method, headers, and body match the API requirements. - **CORS** Some APIs do not accept requests from browsers for security reasons. By default, Wized sends requests from the browser, which can cause issues in these cases. ### How to troubleshoot To determine if the request is failing before reaching the API: 1. **Check the logs** - If the request was not sent, you might see a `500 - Failed to Fetch` error in the **data store panel** under the "States" tab. 2. **Review your request configuration** - Ensure the endpoint URL, HTTP method, headers, and body are correctly set in the **Requests panel**. 3. **Verify API availability** - Visit the API provider’s status page or check online for service interruptions. 4. **Use secrets or native integrations** - If the API blocks direct browser requests, use the [Secrets](/data-store/secrets) feature in Wized to send requests through our servers. - Alternatively, check if Wized has a **native integration** with the service, as these integrations manage API communication securely. --- ## When the request returns an error If the request is successfully sent but the API returns an error, the response will include an **HTTP status code** that indicates what went wrong. ### Common API error codes - **400 Bad Request** – The request is malformed or missing required data. - **401 Unauthorized** – Authentication is required but missing or incorrect. - **403 Forbidden** – The request is valid, but you lack the necessary permissions. - **404 Not Found** – The requested resource does not exist. - **500 Internal Server error** – The API encountered an unexpected issue. View code [list](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status) ### How to troubleshoot 1. **Check the HTTP status code** - In the **data store panel**, look at the status code in the "Statuses" tab. - Use API documentation or online references to understand the meaning of the error. 2. **Examine the response body** - Some APIs provide detailed error messages inside the response body. - Check the **"Body" tab** in the data Store Panel for additional details. 3. **Consult the API documentation** - API documentation will clarify possible causes and solutions for specific errors. # Intro to requests **Requests** allows your project to interact with external web services through REST APIs. This means you can send and receive data, enabling communication with backends, databases, third-party services, payment gateways, and more. # Memberstack Requests The [Memberstack](https://www.memberstack.com/) integration enables granular control over user access to your application, as well as managing user data and subscriptions. ## How to use Memberstack in Wized Memberstack can be used as a standalone App in Wized or in conjunction with Memberstack's `