Migration To Framework7 v2
Stable Framework7 v2 was recently released with the new v2 documentation. And in case you have already created or started to work on app with Framework7 v1 you may want to switch it to v2.
Do you need to switch? Well, in case you have a fully functional and released app made with v1, and you are not going to implement there new features and you are happy with its performance and functionality then you, probably, don't need to change your app to v2. But in case your app is still in development or you are going to release updates for your existing app then v2 is a must. It has much more features, less bugs, and of course this is the main version/branch that will be maintained in future (including new features and bug fixes).
In this guide we will check what need to be done/changed in your Framework7 v1 app to switch it to v2. Note, this guide is for vanilla Framework7 version, Framework7-Vue/React guides will be published later.
Assets
First of all, new F7 has new JS & CSS assets structure.
Stylesheets
- now there is no more separate "colors" stylesheet, all color themes are embedded now into main stylesheets
- there is no more additional RTL stylesheet that you added in addition to main stylesheet to enable RTL styles. Now it is standalone stylesheet file that must be included instead of usual/ltr one
- theme-related styles (for iOS theme and MD theme) are also now in main styles
So here is the list of stylesheet files you will find in /dist/css/
folder:
- framework7.css - main styles bundle. Contains everything in default (LTR) direction: all color themes, iOS theme and MD theme
- framework7.ios.css - contains iOS-only style. Useful only in case you develop app with only iOS theme
- framework7.md.css - contains MD-only style. Useful only in case you develop app with only MD theme
- framework7.rtl.css - RTL bundle. Contains everything in RTL direction: all color themes, iOS theme and MD theme
- framework7.rtl.ios.css - RTL styles only for iOS theme. Useful only in case you develop RTL app with only iOS theme
- framework7.rtl.md.css - RTL only for MD theme. Useful only in case you develop RTL app with only MD theme
And same minified files:
- framework7.min.css
- framework7.md.min.css
- framework7.ios.min.css
- framework7.rtl.min.css
- framework7.rtl.ios.min.css
- framework7.rtl.md.min.css
So if in v1 you have supported both iOS and MD themes you had conditional include of the framework7.ios.css
+ framework7.ios.colors.css
+ framework7.material.css
+ framework7.material.colors.css
. Now you need to include only one stylesheet framework7.css
(or its minified version).
If you used RTL layout with both themes, you had even more files included: framework7.ios.css
+ framework7.ios.colors.css
+ framework7.ios.rtl.css
+ framework7.material.css
+ framework7.material.colors.css
+ framework7.material.rtl.css
. Now you need to include only one stylesheet framework7.rtl.css
(or its minified version).
Scripts
In terms of script files not much changed in case you included them via <script>
attribute. There are same scripts you will find in /dist/js/
folder:
- framework7.js - Framework7 library with all its components
- framework7.min.js - its minified version
But if you included it using ES import
then there are a lot of new things here, now Framework7 and all of its components available as ES modules, check the Installation Docs
App HTML Layout
HTML layout of many components and main app layout is a bit changed. In v1 we had:
<body>
<!-- Statusbar overlay -->
<div class="statusbar-overlay"></div>
<!-- Panels -->
<div class="panel panel-left">...</div>
<div class="panel panel-right">...</div>
<!-- Views -->
<div class="views">
<!-- Your main view, should have "view-main" class -->
<div class="view view-main">
<!-- Pages container, because we use fixed navbar and toolbar, it has additional appropriate classes-->
<div class="pages navbar-through toolbar-fixed">
<!-- Page, "data-page" contains page name -->
<div data-page="index" class="page"></div>
</div>
</div>
</div>
</body>
<!-- Navbar -->
<div class="navbar">
<div class="navbar-inner">
<div class="center">Awesome App</div>
</div>
</div>
<!-- Toolbar -->
<div class="toolbar">
<div class="toolbar-inner">
<!-- Toolbar links -->
<a href="#" class="link">Link 1</a>
<a href="#" class="link">Link 2</a>
</div>
</div>
<!-- Scrollable page content -->
<div class="page-content">
<p>Page content goes here</p>
<!-- Link to another page -->
<a href="about.html">About app</a>
</div>
What we need to change here:
statusbar-overlay
has been renamed to juststatusbar
. Check Statusbar docsviews
element is not required anymore for single view app. It is only required for so called "Tabbed app layout" with multiple views-tabs. Check App Layout docsdata-page
page's attribute renamed todata-name
and also not required anymore- All navbar/toolbar related layout classes are gone and not used anymore
navbar-through
,navbar-fixed
,toolbar-through
,toolbar-fixed
, etc. Check Navbar and Toolbar docs <div class="pages">
element that was used to wrap all view's pages is also gone and not needed anymore- It is now recommended to wrap an app into single root element, for example
<div id="#app"></div
- Navbar's
center
element renamed totitle
So in v2 we will have the following:
<body>
<!-- App root -->
<div id="app">
<!-- Just "statusbar" now -->
<div class="statusbar"></div>
<!-- Panels -->
<div class="panel panel-left">...</div>
<div class="panel panel-right">...</div>
<!-- No more views -->
<div class="view view-main">
<!-- No more "pages" element and navbar/toolbar related classes -->
<!-- "data-page" renamed to "data-name" -->
<div data-name="index" class="page">
<!-- Navbar and Toolbar are always first elements in the page-->
<!-- Navbar -->
<div class="navbar">
<div class="navbar-inner">
<div class="title">Awesome App</div>
</div>
</div>
<!-- Toolbar -->
<div class="toolbar">
<div class="toolbar-inner">
<!-- Toolbar links -->
<a href="#" class="link">Link 1</a>
<a href="#" class="link">Link 2</a>
</div>
</div>
<!-- Scrollable page content -->
<div class="page-content">
<p>Page content goes here</p>
<!-- Link to another page -->
<a href="about.html">About app</a>
</div>
</div>
</div>
</div>
...
</body>
One more important change, now whole HTML structure must be the same for both iOS and MD themes. There is no more any layout difference between them!
iOS Dynamic Navbar
One of the v1 pains was Dynamic Navbar structure, v1 required you to put it under View
element outside of Page
, this produced a lot inconvenience in case you have to maintained both iOS and MD themes in your app. Now such requirement is gone as well, and now Navbar must be always a direct child of the page, and F7 will automatically move it under the View element if it is necessary.
New Components API
First of all, there is a new components API structure. All components that require initialization have new API now. For example in v1 to init/create component we had to call something like app.[componentName](params)
, for example:
app.popup(...)
- to create and open Popupapp.virtualList(...)
- to create Virtual Listapp.calendar(...)
- to create Calendar
In v2 all components API naming convention is new. It is now app.[componentName].create(params)
, for example:
app.popup.create(...)
- to create Popup instanceapp.virtualList.create(...)
- to create Virtual Listapp.calendar.create(...)
- to create Calendar
All these .create()
methods return initialized component instance with own methods, events and properties. For example:
var popup = app.popup.create(...);
// open popup
popup.open();
There are also new additional app methods for such components:
app.[componentName].get(el)
- returns initialized component instance (with.create
) by passed HTML elementapp.[componentName].destroy(el)
- destroys initialized component instance by passed HTML element
And some components has additional app methods related to components. So if you use components with initialization then it is highly recommended to check their documentation.
New/Reworked Components Layout
HTML layout structure of many components has been changed, renamed or simplified. Here are some changes for commonly used components:
List View
- List element class changed from
list-block
to justlist
Content Block
- Content Block. Content block element class changed from
content-block
to justblock
- Content block title element class changed from
content-block-title
to justblock-title
content-block-inner
element (for additional block highlighting) has beed removed and replaced with just an additionalblock-strong
class on the block, so now it should be<div class="block block-strong">...</div>
Navbar
- As mentioned above, its
center
element with page title renamed totitle
Subnavbar
Subnavbar content must be wrapped with additional <div class="subnavbar-inner">...</div>
element:
<div class="subnavbar">
<div class="subnavbar-inner">... subnavbar links or buttons ...</div>
</div>
Form Inputs
Form inputs layout that used in List View a bit changed:
- List item's
item-content
element that contains form input must have additionalitem-input
class. In v1 "item-input" class was added to input element itself - Input element itself must be wrapped with additional
<div class="item-input-wrap"></div>
element - Input label element now is
<div class="item-title item-label">
. In v1 it was<div class="item-title label">
<!-- So, in v1 it was: -->
<li>
<div class="item-content">
<div class="item-media">... icon/image here ...</div>
<div class="item-inner">
<div class="item-title label">Name</div>
<div class="item-input">
<input type="text" name="name" />
</div>
</div>
</div>
</li>
<!-- In v2 the same will be: -->
<li class="item-content item-input">
<div class="item-media">... icon/image here ...</div>
<div class="item-inner">
<div class="item-title item-label">Name</div>
<div class="item-input-wrap">
<input type="text" name="name" />
<span class="input-clear-button"></span>
</div>
</div>
</li>
And now all input labels are stacked by default (not inline like in v1), there are also a lot of new additional elements and configuration for input elements. Check the Form Inputs docs for more info
Messages
Well, Messages component has been fully reworked, so everything is new here from html layout to API. So it is worth to check Messages docs
Searchbar
Searchbar has a bit changed layout:
<!-- In v1: -->
<form class="searchbar">
<div class="searchbar-input">
<input type="search" placeholder="Search" />
<a href="#" class="searchbar-clear"></a>
</div>
<a href="#" class="searchbar-cancel">Cancel</a>
</form>
<!-- In v2: -->
<form class="searchbar">
<div class="searchbar-inner">
<div class="searchbar-input-wrap">
<input type="search" placeholder="Search" />
<i class="searchbar-icon"></i>
<span class="input-clear-button"></span>
</div>
<span class="searchbar-disable-button">Cancel</span>
</div>
</form>
Where we can see:
- new additional "search-inner" element to wrap searchbar content
- "searchbar-input" renamed to "searchbar-input-wrap"
- new seach icon
- "searchbar-clear" renamed to "input-clear-button"
- "searchbar-cancel" renamed to "searchbar-disable-button"
And of course there is new API. Check the Searchbar component docs
Floating Action Button (FAB)
FAB layout and API is also changed to be more unified across iOS and MD themes and support new features, including fab position specific classes.
<!-- In v1 we had: -->
<a href="#" class="floating-button">
<i class="icon icon-plus"></i>
</a>
<!-- Now in v2 it is: -->
<div class="fab fab-right-bottom">
<a href="#">
<i class="icon f7-icons">add</i>
</a>
</div>
FAB Speed Dial comes with new layout as well:
<!-- In v1 it was: -->
<div class="speed-dial">
<a href="#" class="floating-button">
<i class="icon icon-plus"></i>
<i class="icon icon-close"></i>
</a>
<!-- Speed Dial Actions -->
<div class="speed-dial-buttons">
<a href="#">1</a>
<a href="#">2</a>
<a href="#">2</a>
</div>
</div>
<!-- In v2 it has changed to: -->
<div class="fab fab-right-bottom">
<a href="#">
<i class="icon icon-plus"></i>
<i class="icon icon-close"></i>
</a>
<!-- Speed Dial Actions -->
<div class="fab-buttons fab-buttons-bottom">
<a href="#">1</a>
<a href="#">2</a>
<a href="#">3</a>
</div>
</div>
Notifications/Toast
In v1 there was a mess with Notification/Toast component, it was rendered similar to native system notification look in iOS theme and as a Toast in MD theme.
In v2 such inconsistency removed and now there are two different components instead:
- Notification - look like a system notifications on both iOS and MD themes
- Toast - look like a Toast message on both iOS and MD themes
So just check the Notification and Toast documentation on new API and usage examples
Checkbox/Radio
Checkboxes and radios used in List View now has new and unified layout for both iOS and MD themes:
<div class="list">
<ul>
<!-- Single checkbox item -->
<li>
<label class="item-checkbox item-content">
<!-- Checkbox input -->
<input type="checkbox" />
<!-- Checkbox icon -->
<i class="icon icon-checkbox"></i>
<div class="item-inner">
<!-- Checkbox Title -->
<div class="item-title">Books</div>
</div>
</label>
</li>
<!-- Single radio item -->
<li>
<label class="item-radio item-content">
<!-- Radio input -->
<input type="radio" name="my-radio" value="radio-1" />
<!-- Radio icon -->
<i class="icon icon-radio"></i>
<div class="item-inner">
<!-- Radio Title -->
<div class="item-title">Books</div>
</div>
</label>
</li>
...
</ul>
</div>
Tabs
There is not much changes in Tabs:
- Active tab HTML element class renamed from
active
totab-active
- API function to show tab changed from
app.showTab
toapp.tab.show
There are also some new features as Routable Tabs, so check the Tabs documentation.
Buttons & Links
Just few changes here:
- active button element class in Buttons Row/Segmented renamed from
active
tobutton-active
- active tab link element class renamed from
active
totab-link-active
- Buttons Row now called Segmented, so
<div class="buttons">
renamed to<div class="segmented">
Check the Button and Link components documentation for all changes and new features.
Switch/Toggle
Switch component in v1 has been renamed to Toggle, it has new HTML layout and now it must be initialized using JavaScript API or auto initialization:
<!-- In v1 -->
<label class="label-switch">
<input type="checkbox" />
<div class="checkbox"></div>
</label>
<!-- In v2, with auto init -->
<label class="toggle toggle-init">
<input type="checkbox" />
<span class="toggle-icon"></span>
</label>
It is worth to check new Toggle component documentation about all features and new API
Range Slider
As Switch/Toggle, Range Slider now uses JavaScript API and must be initialized manually or automatically in order to work. It has much better support than the older one which was just styled input:range, it has much more new features including dual-range support. Just check Range Slider documentation on how to use it now.
Control Links
As you know there are so called control links in v1, that can trigger some components' actions, like open/close panel, popup, sortable, and other components. In v1 we could have something like:
<!-- Open/Close Panel -->
<a href="#" class="open-panel">Open Panel</a>
<a href="#" class="close-panel">Close Panel</a>
<!-- Open/Close Popup -->
<a href="#" class="open-popup">Open Popup</a>
<a href="#" class="close-popup">Close Popup</a>
In v2 there are same links there only difference is that such additional classes naming convention has beed changed from [action]-[component]
(open-panel, close-popup) to [component]-[action]
. So the same in v2 will be:
<!-- Open/Close Panel -->
<a href="#" class="panel-open">Open Panel</a>
<a href="#" class="panel-close">Close Panel</a>
<!-- Open/Close Popup -->
<a href="#" class="popup-open">Open Popup</a>
<a href="#" class="popup-close">Close Popup</a>
You can find such links reference in related component documentation, e.g. Control Panel With Links, Control Popup With Links, etc.
Request/Ajax API
Ajax API has been removed from built-in Dom7 library ($.ajax, $.get, $.post, $.getJSON) and moved under app.request
method with same functionality and API:
$.ajax(parameters)
->app.request(parameters)
$.get(...)
->app.request.get(...)
$.post(...)
->app.request.post(...)
$.getJSON(...)
->app.request.json(...)
$.ajaxSetup(...)
->app.request.setup(...)
Init App
In v1 we init app using new Framework7
declaration and passing all possible parameters here. In v2 not much changed, except that now components related parameters are now "grouped" and must be passed in separate parameters properties.
So, if in v1 we had and app with such parameters:
var app = new Framework7({
material: true, // enabled material theme
cache: false,
tapHold: true,
uniqueHistory: true,
pushState: true,
panelLeftBreakpoint: 768,
swipePanel: 'left',
modalTitle: 'My App',
popupCloseByOutside: true,
smartSelectOpenIn: 'popup',
smartSelectSearchbar: true,
hideNavbarOnPageScroll: true,
scrollTopOnNavbarClick: true,
imagesLazyLoadThreshold: 50,
statusbarOverlay: true,
scrollTopOnStatusbarClick: true,
});
In v2 it will be :
var app = new Framework7({
theme: 'md',
routes: [
/* ... */
],
touch: {
tapHold: true,
},
view: {
xhrCache: false,
pushState: true,
uniqueHistory: true,
},
panel: {
leftBreakpoint: 768,
swipe: 'left',
},
dialog: {
title: 'My App',
},
popup: {
closeByBackdropClick: true,
},
smartSelect: {
openIn: 'popup',
searchbar: true,
},
navbar: {
hideOnPageScroll: true,
scrollTopOnTitleClick: true,
},
lazy: {
threshold: 50,
},
statusbar: {
overlay: true,
scrollTopOnClick: true,
},
});
Common app parameters like theme
in the above example can be found in App Parameters documentation. Components related parameters can be found on each component page: Popup, Navbar, View, Panel, etc.
Router & Routes
Well, this is some absolutely new and totally reworked in v2.
How the routing works in v1: when we click on any link, then Router will load page by XHR request to url specified in link's href
attribute. So if we click a link <a href="about.html">About Page</a>
, router will load page from about.html file.
In v2 thins are totally different. When we click a link (or use router's api to load a page), it will first check what Route matches to link's url specified in href
tag (or passed url in router api call), and then decides how to load the page for this link based on route parameters.
So first of all, we must pass app routes on app init. For example:
// Init App
var app = new Framework7({
// Pass app routes on app init*
routes: [
{
path: '/about/',
url: './pages/about.html',
},
{
path: '/news/',
url: './pages/news.html',
},
{
path: '/people/',
componentUrl: './pages/people.html'
},
{
path: '/users/:userId/',
componentUrl: './pages/user.html',
}
],
// other app parameters
...
})
What does it mean? According to routes specified above:
- When we click on link with
/about/
href attribute, page will be loaded from/pages/about.html
file - When we click on link with
/news/
href attribute, page will be loaded from/pages/news.html
file - When we click on link with
/people/
href attribute, page will be loaded from/pages/people.html
file as a Router Component - When we click on link with
/users/25/
href attribute, page will be loaded from/pages/user.html
file as a Router Component and it will receiveuserId: 25
route paremeter
That was the basics. There is much more to learn about v2 Router. Here is what is recommended to read/check:
- Mastering Framework7 v2 Router tutorial
- Routes documentation - learn how to and where to specify Routes, all possible parameters and options
- Router Component documentation - learn what is Router Component and what is it for
- View / Router documentation - common Router settings and API
What is Next?
This was the basic guide to migrate your app made with Framework7 v1 to v2. Of course there are a lot more new features which are out of the scope for this guide. As next steps it is highly recommended to check all new Framework7 v2 Docs and Framework7 v2 Starter Templates. And don't forget about Framework7 Forum - the best place to get F7 support.