Onsen UI: Hybrid App & PWA Framework
Onsen UI is an open-source, framework-agnostic HTML5 UI framework designed for creating native-feeling Progressive Web Apps (PWAs) and hybrid mobile applications. Built on Web Components, it provides a rich set of pre-built UI components that automatically adapt to both iOS (Flat) and Android (Material) design guidelines from a single codebase. It is currently at version 2.12.8, with an active release cadence focusing on bug fixes, performance improvements, and minor new features within the 2.x major line. Key differentiators include its pure JavaScript/Web Component foundation, allowing usage without any JavaScript framework, alongside official binding packages for popular frameworks like React, Angular, and Vue. It emphasizes ease of use, optimized animations for mobile, and seamless integration with Cordova/PhoneGap.
Common errors
-
ReferenceError: ons is not defined
cause The Onsen UI JavaScript file was not loaded or was loaded incorrectly, or in an ESM context, the 'ons' object was not explicitly imported or assigned to the global scope.fixEnsure `onsenui.min.js` is included in your HTML `<head>` or before your scripts. If using ES Modules, ensure `import ons from 'onsenui/esm';` is present and potentially `window.ons = ons;` if relying on the global object. -
Uncaught DOMException: Failed to execute 'define' on 'CustomElementRegistry': the name "ons-page" has already been used with this registry
cause The Onsen UI component scripts (or specific element modules in ESM) are being loaded multiple times, attempting to re-register a custom element that is already defined.fixCheck for duplicate script tags for `onsenui.min.js` or `onsenui.js`. If using ES Modules, ensure you are only importing `onsenui/esm` and individual element modules once across your application bundle. -
Custom element 'ons-page' has not been defined
cause You are using an Onsen UI custom element tag in your HTML, but the corresponding JavaScript for that component has not been loaded or registered yet.fixVerify that `onsenui.min.js` (or the specific ESM element imports like `onsenui/esm/elements/ons-page`) is correctly included and loaded before the custom element is rendered in the DOM. Place script tags at the end of `<body>` or use `ons.ready()` for DOM interactions.
Warnings
- breaking The `expanded` CSS class for `ons-list-item` was renamed to `list-item--expanded`.
- breaking The `onClick` callbacks for `ons-tab`, `ons-back-button`, and `ons-speed-dial` no longer automatically prevent default browser behavior. You must now explicitly call `event.preventDefault()` within your callback if you wish to prevent default actions.
- gotcha When using Onsen UI in an ES Module (ESM) environment with a bundler (e.g., Webpack, Rollup), importing `onsenui` directly (`import 'onsenui';`) will include all components. For smaller bundle sizes, import the `ons` object from `onsenui/esm` and then manually import only the specific custom elements your application uses from `onsenui/esm/elements/`.
- gotcha Onsen UI relies heavily on Web Components. Direct DOM manipulation or framework-specific rendering might interfere with component lifecycle or styling if not done carefully. Ensure components are properly initialized and registered before use.
Install
-
npm install onsenui -
yarn add onsenui -
pnpm add onsenui
Imports
- ons
import { ons } from 'onsenui'; // For general use, not how the global 'ons' object is exposed via ESM const ons = require('onsenui'); // CommonJS import for ESM-first libraryimport ons from 'onsenui/esm'; // ... then optionally individual components import 'onsenui/esm/elements/ons-page';
- OnsGlobal
import type { OnsGlobal } from 'onsenui'; - ons-page (custom element)
<!-- In HTML --> <ons-page> <ons-toolbar> <div class="center">My App</div> </ons-toolbar> Page Content </ons-page>
Quickstart
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
<title>Onsen UI Quickstart</title>
<link rel="stylesheet" href="https://unpkg.com/onsenui/css/onsenui.css">
<link rel="stylesheet" href="https://unpkg.com/onsenui/css/onsen-css-components.css">
<script src="https://unpkg.com/onsenui/js/onsenui.min.js"></script>
<script type="text/javascript">
// Ensure Onsen UI is ready before interacting with its components or global 'ons' object
ons.ready(function() {
console.log('Onsen UI is ready!');
// Example: Pushing a new page programmatically
document.addEventListener('init', function(event) {
var page = event.target;
if (page.id === 'main-page') {
var button = page.querySelector('#push-button');
button.onclick = function() {
// The navigator exists if declared in HTML
ons.notification.alert('Hello from Onsen UI!');
};
}
});
// Another way to push a page, e.g., after an event or data load
// const navigator = document.querySelector('ons-navigator');
// if (navigator) {
// navigator.pushPage('next-page.html', { animation: 'lift' });
// }
});
</script>
</head>
<body>
<ons-navigator swipeable id="app-navigator" page="main-page.html"></ons-navigator>
<template id="main-page.html">
<ons-page id="main-page">
<ons-toolbar>
<div class="center">Home</div>
</ons-toolbar>
<div class="content">
<section style="margin: 16px; text-align: center;">
<p>Welcome to Onsen UI!</p>
<ons-button id="push-button">Say Hello</ons-button>
</section>
</div>
</ons-page>
</template>
</body>
</html>