A library to include Ionic in your Svelte and SvelteKit app
NPM library to go along with the Ionic Svelte integration demonstrated at https://ionic-svelte.firebaseapp.com.
On the CLI just type npm create ionic-svelte-app@latest
to spin a SvelteKit project from the CLI. This will
do all the lifting for you to create a SvelteKit SPA app.
A showcase app for all Ionic UI elements, Supercharged by SvelteKit can be found at https://ionic-svelte.firebaseapp.com. This also has a handy tool to show the source code for Svelte - and even Angular, VanillaJS, Vue, React and stencil!
And the code on how to use the components - repo at https://github.com/Tommertom/svelte-ionic-app/tree/main/demo-app
Start a new SvelteKit project (or Svelte with Vite, even though I prefer Kit). Skip this part if you already have a project
npm create svelte@latest my-app
cd my-app
npm install
We need adapter static + ssr=false
, because Ionic package cannot run in SSR=true.
I am chosing to deploy via adapter-static (to Firebase hosting), but if you deploy to Cloudflare, Vercel or Netflify you can opt to do differently. I checked with Vercel and that works still very well.
npm i -D @sveltejs/adapter-static
import adapter from '@sveltejs/adapter-static'
in svelte.config.js
npm remove @sveltejs/adapter-auto
adapter: adapter({
pages: 'build',
assets: 'build',
fallback: 'index.html',
precompress: false
})
src/routes/+layout.ts
and add export const ssr = false;
Integration of Ionic
npm i @ionic/core ionic-svelte
+layout.svelte
(Kit) or top root module (others) needs to run setupIonicSvelte()
and import the theme stylesheet before anything else - also see starterfiles/+layout.svelte. Example:<script lang="ts">
import { setupIonicBase } from 'ionic-svelte';
/* Theme variables */
import '../theme/variables.css';
/* load and register all components - you can also import separately to code split */
import 'ionic-svelte/components/all';
/* run base configuration code from ionic/core */
setupIonicBase();
</script>
<ion-app>
<slot />
</ion-app>
And then start working on the content of the app in +page.svelte
:
Hi there <ion-button>test</ion-button>
If you get a 500 internal error-error then likely SSR is not disabled. Making a SvelteKit app a real SPA really requires two steps - adapter static and ssr=false
Starterfiles on github: https://github.com/Tommertom/svelte-ionic-app/tree/main/starterfiles Use these files as reference to see how to do the final steps integrating Ionic in your svelte project.
Code for this library - https://github.com/Tommertom/svelte-ionic-app
Ionic-svelte on NPMjs- https://www.npmjs.com/package/ionic-svelte
In order to reduce bundle size or limit the size of individual chunks, you can replace the import in main layout file. Example: if you replace the line import 'ionic-svelte/components/all';
with imports like below. This can reduce the bundle for that chunk drastically. The import of all
will result to at least an 800kb chunk (80 components), so it is worth it to change this.
Next you can choose to load specific components only where you use them.
Please note, you only need to import a component only once, as the import registers the webcomponent globally. So this saves you lots of imports, reducing the bundle as well (compared to tree-shaking).
And never forget to at least import 'ionic-svelte/components/ion-app';
- as this one is in the main layout.
import 'ionic-svelte/components/ion-app';
import 'ionic-svelte/components/ion-card';
import 'ionic-svelte/components/ion-card-title';
import 'ionic-svelte/components/ion-card-subtitle';
import 'ionic-svelte/components/ion-card-header';
import 'ionic-svelte/components/ion-card-content';
import 'ionic-svelte/components/ion-chip';
import 'ionic-svelte/components/ion-button';
Ionic components are webcomponents, so appear in your template just like other dom elements. They don't need ECMA imports like import {IonCard} from '...
.
<ion-card>
Here content
</ion-card>
So you can also apply css classes to them, also when wanting to tweak UI via the shadow dom/web-parts.
Due to router issues and overlays, there are three special compontents included that override/replace the ionic standard webcomponents:
To be imported from the package: import { IonTab } from 'ionic-svelte';
etc..
See HOWTOs on how to implement tabs and nav. For Page - just check https://ionic-svelte.firebaseapp.com/
https://github.com/Tommertom/ionic-svelte-tabs-howto
https://github.com/Tommertom/ionic-svelte-nav-howto
The package provides typings for all webcomponents. These can be included in your IDE by adding the following to your the compilerOptions
section in tsconfig.json
:
"typeRoots": [
"./node_modules/ionic-svelte"
],
"types": [
"ionic-svelte"
]
Sample tsconfig.json
:
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"typeRoots": [
"./node_modules/ionic-svelte"
],
"types": [
"ionic-svelte"
]
}
}
Would you like to contribute to this project? Great!
First and foremost - share you feedback!!!!!
ionic-svelte
library - https://github.com/Tommertom/svelte-ionic-npm/issuesAnd if you want to do more - what is there to do:
When you do a PR, make sure you explain what you did and why!
Ion Back Button - requires default-href
to show in toolbar (page transitions need to add can-go-back
class)
IonTabs needs to manually call the select method of ion-tabs to ensure the selectedTab prop is really acted upon. Issue known: https://github.com/ionic-team/ionic-framework/issues/20060. Gives a brief undesireable view on the wrong tab. Might need to look into the angular/react/vue way as these packages don't have this issue. Probably tabs is wired up in the router.
Gestures: Need a timeout to get proper style value even though I am using onMount??
Ion Footer in Modal looks not ok - need to test in inline modal as well.
bind:value does not seem to work on input and other form elements, so a click handler is needed - which is cumbersome - https://github.com/sveltejs/svelte/issues/892 - so probably not solvable without support by Ionic or Svelte - or we need to create wrappers for all elements - which is quite some work and you will be required to manually import all elements you use per page (like with Vue and React) - which seems a drag to me?
SvelteKit form actions make the usage of bind:value even obsolete. So that is the go-to way route anyway - https://kit.svelte.dev/docs/form-actions
Please note - if you use a library such as https://svelte-forms-lib-sapper-docs.vercel.app/introduction together with Yup schemas https://github.com/jquense/yup, the bind:value-issue actually becomes less relevant as you will have the library handle the events and you will use the observables to manage validation and final values to use for further processing. See https://blog.logrocket.com/form-validation-in-svelte/ for nice examples.
Some styles are reported as unused - related to md and ios options for webcomponents? Or need to be discarded. Probably issue with webcomponents and the nature of Ionic being sensitive to md or ios style (as part of its config). Or the way Svelte/vite checks for unused css.
Add IonPage, IonTabs and IonBackButton are not part of the default export - these are svelte components, so index.ts cannot handle these (?)
Ion Icons implementation only uses icon-property syntax. Name/md/ios will not function
In some cases IonPage clips the content enclosed - then you need to remove main tags in IonPage
Routerlink, href and similar props on components like ion-item do not work properly, but I wonder if support is needed
Menucontroller does not see the menu by default - you need to register the menu item manually - extra function added to help you with that (registerMenu(menu-id:string)
) - <ion-menu {side} content-id="main" menu-id="mainmenu">
see Menu.svelte with working example
Nav component - works nicely, but implementation might be dirty (leaking DOM elements?). ion-nav-link not implemented.
ItemSliding sometimes does not catch the gesture - known issue - needs fix in @ionic/core
Many "File not found errors" on css.map files in the demo app. I frankly don't really mind these. Maybe it is easy to get rid of these, but for now, I leave it.
Check https://github.com/Tommertom/svelte-ionic-app/issues for most recent overview of issues.
ion-router-link
, ion-router
,ion-route
, ion-route-redirect
and ion-router-outlet
- these are imho obsolete because of usage of the router in this project. But tell me if I am wrong here!
ion-nav-link
- not sure why not, but haven't used it yet in a project. Maybe my bad. What do you think?
Logo by Brett Peary: https://brettpeary.com/
Ionic UI code: https://github.com/ionic-team/ionic-docs/tree/main/static/demos/api
README inspiration: https://github.com/gitpoint/git-point/blob/master/README.md
PWA logo: https://github.com/webmaxru/progressive-web-apps-logo
Borat logo: https://sapper.svelte.dev/
Raymondboswel's repo: https://github.com/raymondboswel/ionic-svelte-example