Skip to content

Standards-Based Frontend ​

ioLoop frontends run in the browser using standard HTML, CSS, and JavaScript.

The Page Editor, Page Elements, Forms, Widgets, Page Flow, Media, Frontend Code assets, HTML Head Additions, and ioLoop Client API provide complementary ways to build browser-based applications. Creators can use the built-in tools, write custom frontend code, or combine both approaches in the same Project.

Fully custom frontend development is a supported, first-class approach in ioLoop. A Project is not limited to the components available in the visual editor or the blocks provided by Page Flow.

Most importantly, ioLoop's built-in Forms, Widgets, and Page Flow blocks use the same ioLoop Client APIs that custom frontend JavaScript can call directly. This means a custom implementation can achieve the same functional results as a corresponding built-in component. The choice is how the functionality is implemented and maintained, not whether custom code has access to a different or reduced set of Client API capabilities.

One Client API Foundation ​

The ioLoop Client API is the common programming foundation for browser-side Project functionality.

Development ApproachHow It Uses ioLoop Functionality
Page Flow blocksProvide visual programming controls that use ioLoop Client API functionality for browser-side behavior.
FormsPackage field handling, validation, submission, status, and modal workflows into ready-made experiences built on Client API capabilities.
WidgetsPackage data display, interaction, and other specialized features into configured components built on Client API capabilities.
Custom JavaScriptCalls the same ioLoop Client APIs directly to build equivalent or more specialized frontend workflows.

For example, a Creator can build a customer-management interface using a Data Table Widget and a Table-Backed Form, or write a fully custom customer list and modal Form using HTML, CSS, JavaScript, and ioLoop Client APIs. Both approaches can read permitted records, create and update records, and refresh the interface. The custom implementation simply manages its own presentation, event handling, and lifecycle.

Likewise, a Page Flow built from visual blocks can be implemented in custom JavaScript that directly invokes the corresponding Client API functionality. The built-in tools reduce the amount of code a Creator must write; they do not reserve those underlying capabilities for themselves.

The same access rules apply in either approach. Direct Client API calls are still subject to the Project's Database permissions and other applicable security controls. Trusted work requiring protected credentials or server-enforced authorization belongs in Cloud Flow or an appropriate Backend capability regardless of the frontend approach.

For exact available functions, namespaces, arguments, and results, see the Client API reference.

Choosing a Frontend Approach ​

Different application requirements call for different levels of customization.

ApproachBest For
Visual Page ElementsStandard layouts, headings, content, menus, buttons, media, cards, and other editable interface structures.
Page FlowBrowser-side events, validation, navigation, data operations, Form workflows, and coordination with Widgets or Cloud Flow.
Forms as ModalsReady-made modal input experiences with ioLoop-managed fields, validation, submission, and status behavior.
Frontend Code assetsReusable JavaScript and CSS included on one or more Pages or Forms.
HTML Head AdditionsSupported third-party scripts, external stylesheets, metadata, and other document-head resources.
Imported HTMLConverting supported existing HTML content into editable Page Elements.
Custom SPA-style PagesFully custom browser interfaces—including Forms, modals, tables, and interactive components—that directly use the same Client API capabilities as ioLoop's built-in frontend tools.

These approaches are not mutually exclusive. One Page might contain a visually edited header and navigation, Page Flow-driven record actions, custom CSS, and a JavaScript-controlled chart or interactive region.

Start with the implementation approach that best fits the Project's needs. Built-in Forms, Widgets, and Page Flow blocks accelerate common tasks, while custom JavaScript offers direct control over the interface, logic, and lifecycle. These are different levels of abstraction over the same frontend API capabilities, not separate tiers of functionality.

Browser Standards and Runtime Environment ​

An ioLoop frontend runs in the visitor's browser. Its custom code can use browser-standard capabilities available in that runtime, including:

  • HTML elements and the Document Object Model (DOM).
  • CSS selectors, classes, responsive rules, and external stylesheets.
  • JavaScript functions, objects, browser events, and supported browser APIs.
  • Appropriate third-party browser libraries and their documented integration methods.
  • The same supported ioLoop Client API functions used by Page Flow blocks, Forms, and Widgets, including permitted Project data operations.

Normal browser constraints still apply. For example, a third-party resource may be affected by cross-origin rules, Content Security Policy, network availability, library compatibility, or the visitor's browser permissions.

JavaScript module syntax or a library's preferred loading format does not, by itself, mean that every asset inclusion method accepts that format. Follow the loading mechanisms supported by the relevant Frontend Code or HTML Head Additions configuration and test the result in Preview.

Browser-Side Code Is Not Trusted Backend Code ​

HTML, CSS, JavaScript, and data delivered to the browser can be inspected or influenced by the visitor. Never put private keys, secret tokens, protected integration credentials, or authoritative permission decisions in frontend code or HTML Head Additions.

Use Cloud Flow and the appropriate Backend capabilities for operations that require trusted processing, private credentials, or server-enforced rules.

Visual Editing and Custom Code Together ​

ioLoop's visual Page Elements and custom frontend code can coexist on the same Page.

For example, a product catalog might use:

Interface ResponsibilityPossible Implementation
Navigation, headings, and page layoutVisual Page Elements
Product images and reusable frontend assetsMedia
Filter or search controlsPage Elements, Page Flow, or custom JavaScript
Custom product visualizationJavaScript and CSS included through Frontend Code
Permitted product data retrievalSupported Client API or Page Flow data operations
Protected pricing or authorization rulesCloud Flow or trusted Backend logic

A useful design principle is to make ownership explicit. If Page Elements manage a region, use their supported settings and Page Flow operations where possible. If custom JavaScript manages a region, keep its initialization, updates, event listeners, and cleanup together in the custom implementation.

Avoid having both the visual editor's behavior and custom JavaScript independently modify the same interface state unless that interaction is deliberately coordinated.

HTML Import and Visual Editing ​

Import HTML is an editing operation for bringing supported existing markup into the Page Editor.

Typical uses include:

  • Migrating content from an existing website.
  • Reusing an HTML section generated by another tool.
  • Starting from a structured content fragment instead of recreating every element manually.
  • Converting compatible text and layout content into visually editable Page Elements.

Importing HTML ​

A typical workflow is:

  1. Open the Page, Form, or supported Page Slice in the Page Editor.
  2. Select the element or container that should receive the imported content.
  3. Choose Import HTML from the available element actions.
  4. Paste the markup and confirm the import.
  5. Inspect the converted Page Element structure.
  6. Adjust layout, text, links, images, and Element Settings as necessary.
  7. Save and Preview the result.

ioLoop converts supported HTML into editable Page Elements and places them inside the selected destination. The converted structure can then be maintained using normal Page Editor tools.

What HTML Import Does Not Do ​

HTML Import is not a complete website or SPA import mechanism.

The import process filters unsupported and unsafe markup. Scripts, stylesheets, head metadata, iframes, embedded media tags, SVG markup, and other unsupported structures are not imported as working application components. The original site's JavaScript behavior, dependencies, state, and backend integrations are not recreated automatically.

Even supported markup may require visual adjustments after conversion. Do not assume that the imported result will be pixel-identical to the source.

If the imported content requires custom behavior, implement that behavior separately using Page Flow, Frontend Code, or other supported Project capabilities.

For detailed import steps and restrictions, see Editing Page Content.

HTML Block Is Different from HTML Import ​

The HTML Block Page Element gives a content area a supported semantic HTML role, such as section, article, or nav.

It does not serve as a general-purpose raw HTML, JavaScript, or external-application embedding control. Use HTML Block for semantic structure, Import HTML for supported markup conversion, and custom frontend code for application behavior.

See Text and Content for HTML Block guidance.

Frontend Code Assets ​

Use Frontend → Code to create and manage JavaScript and CSS assets authored within the Project.

Code assets are appropriate when behavior or styling should be:

  • Shared by multiple Pages or Forms.
  • Organized separately from the visual Page layout.
  • Reused from Page Flow or other custom browser code.
  • Maintained as named JavaScript or CSS files.
  • Included only on the Pages that need them.

ioLoop supports Page/Form JavaScript and Page/Form CSS Code file types.

Creating and Including Code ​

A typical workflow is:

  1. Open Frontend → Code and create a JavaScript or CSS file.
  2. Add and save its code using the corresponding editor.
  3. Open Project Settings for broad inclusion or Page Settings → Code for Page-specific inclusion.
  4. Select the Code assets to load and configure their order where appropriate.
  5. Save the inclusion settings.
  6. Preview the Page and verify that the code loads and behaves correctly.

Creating a Code file does not automatically include it on every Page. The file must be selected at the appropriate inclusion scope.

For example, a shared formatting helper can be included at Project level, while CSS written for a specialized dashboard can be included only on that dashboard Page.

Load Order and Dependencies ​

Load order matters when one JavaScript asset uses functionality defined by another, or when CSS files define overlapping styles.

If a custom Page needs a charting library and a separate chart helper, configure the library to load before the helper that depends on it. Verify the actual runtime load and initialization behavior rather than assuming that naming or inclusion alone guarantees a dependency is ready.

For full details on creation, editing, access, inclusion, and file actions, see Code.

HTML Head Additions and Third-Party Libraries ​

HTML Head Additions allow supported markup to be included in the HTML document's <head> section. They are available through supported Project-level or Page-level settings.

Typical uses include:

  • Linking to an external stylesheet.
  • Loading an appropriate third-party browser library.
  • Adding specialized metadata not already configured through standard Page Settings.
  • Supplying head-level configuration required by an external browser integration.

For example, a page-specific external stylesheet could be referenced using:

html
<link rel="stylesheet" href="https://example.com/styles.css">

This is illustrative markup; use the actual, trusted URL of the stylesheet you intend to load.

Project-Level vs. Page-Level Head Additions ​

ScopeUse When
Project-levelA supported resource is required broadly throughout the Project.
Page-levelA particular Page or Form requires the resource.

Use page-level additions for specialized dependencies rather than loading them unnecessarily across the application.

For JavaScript and CSS maintained inside ioLoop, prefer Frontend Code assets. Use Head Additions for supported head-level markup and external resources. Avoid duplicating metadata already provided through Page Info, SEO & Social settings.

Third-Party Dependency Considerations ​

Before including a third-party library:

  • Confirm its source is trustworthy and its use is appropriate for the Project.
  • Verify browser compatibility and the library's required loading method.
  • Ensure dependent code runs only after required resources are available.
  • Check for conflicts with existing CSS, JavaScript, Page Elements, and Widgets.
  • Consider library updates, network failures, and performance costs.
  • Test all affected Pages in Preview and after publishing.

A third-party library can provide new presentation and interaction behavior, but loading it does not automatically connect it to Page Flow, Project data, authentication, or ioLoop Widgets.

For configuration details, see Page Settings.

Custom SPA-Style Pages ​

A Page can support a custom SPA-style experience when the Creator prefers to implement and control the interface using standard web development techniques rather than relying primarily on ready-made Page Elements, Forms, Widgets, or visual Page Flow blocks.

In this approach, custom JavaScript manages a substantial portion—or all—of the Page's interface. It can render content, manage state, respond to events, and call the same ioLoop Client APIs used by the built-in frontend components. A custom SPA does not need a corresponding Widget, Form, or Page Flow block in order to use functionality exposed by those APIs.

Examples include:

  • A specialized interactive dashboard.
  • A rich visual editor or configurator.
  • A custom search-and-filter experience.
  • A custom product or booking interface.
  • An application section with its own internal navigation and interaction state.

This does not require abandoning ioLoop's visual tools. A custom interface can live inside a larger Page that still uses managed navigation, layout, Media, Page Flow, and other Project features.

Planning a Custom Interface ​

A practical implementation pattern is:

  1. Create the Page and define the layout or content area where the custom experience belongs.
  2. Configure supported element identifiers or selectors needed to locate that area at runtime.
  3. Create JavaScript and CSS under Frontend → Code.
  4. Include those assets on the Page and load any required third-party dependencies through supported mechanisms.
  5. Initialize the custom experience after its target content and dependencies are available.
  6. Use the ioLoop Client API directly for frontend operations—including behavior that could alternatively be built with Forms, Widgets, or Page Flow blocks—and call trusted Backend operations when required.
  7. Preview and test the complete experience, including cleanup, navigation, and error states.

The Page Editor provides the host Page structure. Custom JavaScript can own the content and behavior of the region you deliberately designate for it.

Example: A Custom Content Region ​

Suppose a Page has an intentionally configured content element with the ID product-results.

A JavaScript Code asset could contain ordinary browser-side code such as:

js
function showProductMessage(message) {
  const target = document.getElementById('product-results');
  if (!target) return;

  const paragraph = document.createElement('p');
  paragraph.textContent = message;
  target.replaceChildren(paragraph);
}

This example demonstrates standard DOM behavior; it is not an ioLoop Client API call. The target ID must actually exist in the rendered Page, and the function must be invoked at the appropriate time by your custom code or a supported Page Flow interaction.

Use this approach for regions intentionally controlled by custom code. For content managed through Page Elements or Data Design, prefer their supported configuration and rendering mechanisms where practical.

SPA Responsibilities ​

When custom JavaScript owns an interface region, the implementation must also manage the behavior that ioLoop's built-in components would otherwise provide.

This may include:

  • State management and UI updates.
  • Event handlers and element lifecycle.
  • Client-side navigation where needed.
  • Form field state and validation.
  • Loading, success, error, and retry experiences.
  • Keyboard interaction, focus management, and accessibility.
  • Responsive layout and mobile interaction.
  • Safe rendering of untrusted content.
  • Cleanup of listeners and other resources when appropriate.

A custom SPA-style Page is still subject to the Project's access settings and Backend security requirements. Custom navigation or hidden UI controls do not grant or enforce authorization.

Custom Modal Interfaces and ioLoop Forms ​

A custom modal interface can implement the same functionality as an ioLoop Form using HTML, CSS, JavaScript, and the same ioLoop Client APIs that support the built-in Form experience. This includes collecting and validating input, creating or updating permitted records, passing context, invoking Cloud Flow, and handling the modal's success, error, and close states.

The difference is implementation convenience and control, not functional capability. The built-in Form provides a ready-made implementation; custom JavaScript can implement equivalent behavior without using an ioLoop Form component.

AreaioLoop Form as ModalCustom Modal Interface Using the Client API
Fields and layoutUses ioLoop-managed Form fields and the Page Editor.Uses custom HTML, CSS, and JavaScript to build the interface.
Input state and validationUses built-in Form behavior, with Form Page Flow where needed.Custom code manages field values and validation, using ioLoop Client APIs as appropriate.
Opening and closingUses supported modal-opening mechanisms and Form outcomes.Custom code manages the modal lifecycle and result handling.
Data operationsUses supported Form submission and Page Flow capabilities.Can use the ioLoop Client API directly for permitted Project data operations.
Cloud Flow and integrationsCan initiate trusted Backend workflows through supported Form and Page Flow mechanisms.Can initiate the same kinds of trusted Backend workflows through the ioLoop Client API.
Success and error experienceUses configured Form status areas and lifecycle behavior.Custom code displays and manages equivalent success, error, loading, and retry experiences.

Example: A custom Add Customer modal can collect customer information, validate it, create a record through the permitted ioLoop Client API, display the result, and refresh a custom customer list. A custom Edit Customer modal can load the selected record, update permitted fields, and refresh the same list. These are the same functional outcomes as the corresponding ioLoop Form and Data Table workflows, but implemented directly in JavaScript. Neither workflow requires the built-in Form or Data Table Widget.

Choose an ioLoop Form when its ready-made field configuration, validation, and modal lifecycle save development effort. Choose a custom modal when you want to implement and control the layout, state, behavior, or interaction model yourself. Both approaches can deliver the same functional result through ioLoop's Client APIs.

A custom modal does not automatically acquire the Form component's lifecycle or visual configuration simply because it uses the Client API; your JavaScript implements the equivalent behavior. Both approaches remain subject to Database access rules and trusted Backend authorization for protected operations.

For ready-made ioLoop Form workflows, see Opening Forms as Modals.

Using the ioLoop Client API ​

Any JavaScript running in the supported ioLoop frontend context can use the ioLoop Client API directly. This includes Page Flow Custom Code, included Frontend Code assets, custom SPA-style Pages, custom modal interfaces, and other browser-side code executing in the Page context. No built-in Widget, Form, or visual Page Flow block is required to access a documented Client API function.

The built-in Widgets, Forms, and Page Flow blocks themselves use these Client APIs. Custom JavaScript therefore does not have a reduced or secondary API surface simply because it bypasses the ready-made controls.

The Client API provides documented functions for Page content, DOM elements, Forms, Project data, user-interface actions, and runtime behavior. The reference organizes them under $io.content, $io.db, $io.dom, $io.form, $io.system, and $io.ui. Custom JavaScript can combine these functions with standard browser APIs to build complete applications.

Common uses include:

  • Reading, creating, updating, or deleting permitted Project records.
  • Building custom Forms or modals that perform the same functional tasks as ioLoop Forms.
  • Building custom record tables with the same functional outcomes as the Data Table Widget.
  • Rendering Project data in custom lists, grids, charts, or interactive content.
  • Managing supported UI operations and interacting with Page elements.
  • Initiating Cloud Flow operations when trusted server-side work is needed.
  • Using supported file interfaces for upload, retrieval, and related workflows.
  • Connecting custom interactions with Page Flow or other Project behavior.

The Client API and Server API are different execution surfaces. Client API operations are still subject to the current user's permissions and browser-side security boundaries. Functions documented only in the Server API should be used from their supported Backend context, not assumed to exist in the browser.

For exact functions, signatures, parameters, return values, and calling conventions, see Client API and Page Flow Blocks.

Frontend Data and Backend Security ​

All custom frontend code can access Project data through ioLoop Client API operations subject to the current user's permissions. When those operations are permitted directly from the browser, a custom Cloud Flow is not required merely to read or update a record.

Use Cloud Flow when an operation requires trusted execution, protected credentials, authorization-sensitive business rules, or external service processing that should not run in the visitor's browser.

For example, a custom registration interface can retrieve permitted event details and submit allowed data directly through the Client API, just as a Page Flow or Form can. When accepting a registration requires an authoritative capacity limit, Cloud Flow can enforce that rule and commit the registration safely. The security requirement is the same regardless of whether the frontend is a built-in Form or custom JavaScript.

Development and Published Behavior ​

During Preview, built-in Database operations automatically use the development database. This applies to supported built-in reads, creates, updates, and deletes, including operations performed through supported frontend interfaces.

Preview does not automatically put unrelated external providers into test mode. Custom code, external libraries, Integrations, and Cloud Flow workflows that contact outside services can still have external effects depending on their configuration.

Before testing, confirm which operations use ioLoop's built-in Database mechanisms and which operations target other services or destinations.

For details, see Previewing and Data and Cloud Flow.

Practical Example: Custom Product Catalog ​

Consider a Project that needs a product catalog with a branded layout, interactive filters, and record-specific actions.

A possible implementation is:

  1. Build the surrounding Page. Use visual Page Elements for branding, navigation, headings, and a section that will contain catalog results.
  2. Prepare Project data. Define the product fields and configure appropriate Database access rules.
  3. Choose the rendering approach. Use Data Design if its repeated layout model meets the need, or custom JavaScript if the interface requires specialized rendering and state management.
  4. Add the styling. Use Frontend Code CSS for shared product-card styles and responsive arrangements.
  5. Implement interactions. Use Page Flow blocks or custom JavaScript for filter changes, selected products, and visible state; both can use the same underlying Client API capabilities.
  6. Retrieve records. Use permitted Client API operations directly, or use the corresponding Page Flow data blocks, handling loading and error results.
  7. Handle protected actions. Invoke Cloud Flow for server-enforced operations when required.
  8. Preview and publish. Test normal results, empty results, long descriptions, mobile layout, permissions, and failures before publishing the Project.

The same general approach applies to custom dashboards, directories, portals, and interactive tools. The division between visual editing and custom code should reflect the application's actual requirements.

Previewing and Testing ​

Test a customized Page as a complete browser experience, not only as a collection of individually working code files.

Check that:

  • All required JavaScript and CSS assets are included at the correct scope.
  • External libraries load successfully and in the required dependency order.
  • Target elements exist before custom initialization runs.
  • JavaScript listeners and Page Flow actions do not conflict or trigger duplicate operations.
  • Imported HTML displays correctly after conversion and visual editing.
  • Custom forms, navigation, and interactive regions behave correctly.
  • Data operations respect the selected user context and Database permissions.
  • Loading, empty, error, and retry states are handled.
  • Responsive layouts work at desktop, tablet, and mobile widths.
  • Browser console errors and failed network requests are investigated.
  • The published application is checked with Launch Project after publishing.

Remember that saving Code files, Page content, Page Flow, and their inclusion settings updates the development state. Preview tests the saved development version; Publish Project releases changes; Launch Project opens the published application.

Good Practices ​

  • Choose clear ownership. Decide which Page regions use ioLoop-managed elements and which are managed by custom JavaScript.
  • Choose built-in or custom implementation deliberately. ioLoop Forms, Widgets, and Page Flow blocks are productivity abstractions over Client API capabilities; custom code can implement equivalent functionality directly.
  • Keep reusable code in Frontend Code. Use named assets and select the appropriate Project-level or Page-level inclusion.
  • Use Head Additions deliberately. Load external resources and specialized head markup only where needed.
  • Treat HTML Import as conversion. Inspect and refine the generated Page Elements instead of assuming it preserves the original application.
  • Document dependencies. Make library requirements, load order, selectors, and initialization behavior understandable to other Creators.
  • Keep sensitive work on the Backend. Never trust a hidden Page control or browser-only validation as authorization.
  • Support accessibility and mobile devices. Test interaction, keyboard behavior, layout, and content readability.
  • Test the full workflow. Include data permissions, external services, errors, and the published experience.

Common Mistakes ​

Avoid these patterns:

  • Assuming the visual editor is the only supported frontend development approach.
  • Expecting Import HTML to preserve scripts, external application logic, or arbitrary unsupported markup.
  • Treating HTML Block as a raw HTML or JavaScript embedding mechanism.
  • Creating a Code asset without including it on the Page or Project.
  • Assuming all third-party library formats work with every script inclusion method.
  • Running custom code before its target elements or dependencies are ready.
  • Letting visual configuration and custom JavaScript compete over the same UI state.
  • Assuming custom frontend code has fewer ioLoop capabilities than Forms, Widgets, or Page Flow blocks.
  • Assuming custom modal interfaces cannot achieve the same results as ioLoop Forms—or assuming they inherit the built-in Form lifecycle automatically without implementing it.
  • Using private credentials or enforcing sensitive permissions only in browser code.
  • Assuming Preview automatically isolates external services or third-party APIs.
  • Publishing without testing the released Page and its dependencies.

ioLoop's built-in Forms, Widgets, and Page Flow blocks use the same Client APIs available to custom JavaScript. Choose visual tools for speed and convenience, custom code for direct control, or combine both—without giving up the underlying ioLoop functionality.