diff --git a/docs/content/1.index.md b/docs/content/0.index.md similarity index 95% rename from docs/content/1.index.md rename to docs/content/0.index.md index 1eed43c7..864229c1 100755 --- a/docs/content/1.index.md +++ b/docs/content/0.index.md @@ -8,7 +8,7 @@ layout: page --- cta: - Get Started - - /getting-started + - /get-started/introduction secondary: - Open on GitHub → - https://github.com/nuxt-modules/ionic diff --git a/docs/content/1.get-started/1.introduction.md b/docs/content/1.get-started/1.introduction.md new file mode 100644 index 00000000..d84cb10f --- /dev/null +++ b/docs/content/1.get-started/1.introduction.md @@ -0,0 +1,55 @@ +--- +navigation.icon: uil:info-circle +description: 'Batteries-included, zero-config needed, Ionic integration for Nuxt' +--- + +# Introduction + +::alert{type="warning"} +⚠️ @nuxtjs/ionic is currently a work in progress. ⚠️ +:: + +`@nuxtjs/ionic` provides a batteries-included, zero-config needed, Ionic integration for Nuxt. + +Supercharge your Ionic apps with the power of Nuxt, giving you the tremendous development experience you're used to +when using Nuxt for web. + +Follow the installation guide to get going immediately, or continue reading to find out more about what this module provides. + +::alert{type="info"} +Get started with our [Installation guide](/get-started/installation). +:: + +## What is Ionic? + +[The Ionic SDK](https://ionicframework.com/) is an open-source UI toolkit for building modern, cross-platform mobile apps from a single codebase. It deeply integrates with Vue for a delightful mobile dev experience. + +::alert{type="info"} +Read the [Ionic documentation for Vue](https://ionicframework.com/docs/vue/overview) to learn more about Vue development with Ionic. +:: + +## Features + +This module attempts to get you going with Nuxt + Ionic quickly, providing sane defaults for ionic and helpful components and utilities. The configuration file can still customize and override its default behaviors and provide full customisation of ionic. + +::list{type=success} +- **Ionic router integration:** continue defining routes based on the structure of your `~/pages` directory and using page-level utilities such as `definePageMeta()`. +- **Auto-imports**: Ionic components, composables and icons are all [auto-imported](https://nuxt.com/docs/guide/concepts/auto-imports) for ease of use. +- **Helpful components and utilities**: This module provides components and utilities to accomplish common tasks more easily. +- **PWA support**: out-of-the-box support for progressive web apps, using `nuxt-pwa-module`. +- **Pre-render routes** +- **Mobile meta tags** +- **Capacitor integration**: works out-of-the-box with [Capacitor](https://capacitorjs.com/) for shipping to native platforms like iOS and Android. +:: + +::alert{type="info"} +Read more about [our features](/overview). +:: + +## Cookbook + +Our cookbook documentation provides common use-cases with code examples to get you going as fast as possible. And if you create something useful, come back and submit a PR to have it added to our cookbook. + +::alert{type="info"} +Discover common recipes in [our cookbook](/cookbook). +:: diff --git a/docs/content/1.get-started/2.installation.md b/docs/content/1.get-started/2.installation.md new file mode 100644 index 00000000..9eab42d8 --- /dev/null +++ b/docs/content/1.get-started/2.installation.md @@ -0,0 +1,80 @@ +--- +navigation.icon: uil:play-circle +description: 'Get started with the ionic module for Nuxt' +--- + +# Installation + +Get started quickly by installing and setting up this module with the following instructions. + +## Prerequisites + +- A fresh or existing Nuxt project +- [Nuxt's prerequisites](https://nuxt.com/docs/getting-started/installation#prerequisites) +- [Ionic's environment setup](https://ionicframework.com/docs/intro/environment) +- [Capacitor's enviroment setup](https://capacitorjs.com/docs/getting-started/environment-setup) if using iOS or Android + +## Installation + +Add `@nuxtjs/ionic` to your project's dev dependencies: + +::code-group + +```bash [yarn] +yarn add --dev @nuxtjs/ionic +``` + +```bash [npm] +npm install @nuxtjs/ionic -D +``` + +```bash [pnpm] +pnpm install @nuxtjs/ionic -D +``` + +:: + +### Nuxt Module + +Next, add the module to your Nuxt configuration in `nuxt.config.ts`. + +```js{}[nuxt.config.ts] +export default defineNuxtConfig({ + modules: ['@nuxtjs/ionic'], + ssr: false, +}) +``` + +::alert{type="warning"} +If deploying to iOS or Android, be aware the app must be able to run completely client-side. We recommend setting `ssr: false` in your nuxt config. Find out more in [deploying to both web and device](/cookbook/web-and-device). +:: + +Finally, either remove your `app.vue` file or [replace it with a custom one](/cookbook/customising-app-vue). + +### Development Server + +Now you'll be able to start your Nuxt app in development mode as usual: + +::code-group + +```bash [yarn] +yarn dev -o +``` + +```bash [npm] +npm run dev -- -o +``` + +```bash [pnpm] +pnpm dev -o +``` + +:: + +::alert{type=success icon=✨ .font-bold} +Well done! A browser window should automatically open for . +:: + +::alert{type=info} +The first time you start a Nuxt project with `@nuxtjs/ionic` enabled, a `ionic.config.json` file will be created if it doesn't already exist. +:: diff --git a/docs/content/1.get-started/3.configuration.md b/docs/content/1.get-started/3.configuration.md new file mode 100644 index 00000000..34ed5b5d --- /dev/null +++ b/docs/content/1.get-started/3.configuration.md @@ -0,0 +1,116 @@ +--- +navigation.icon: uil:wrench +--- + +# Configuration + +This module provides configuration options for itself, as well as passing through configuration for ionic. + +Configuration for capacitor is set in the usual way, via capacitor.config.ts. + +### Module Config + +This module exposes three keys for configuration: `integrations`, `css` and `config`: + +```js [nuxt.config.ts] +export default defineNuxtConfig({ + modules: ['@nuxtjs/ionic'], + ionic: { + integrations: { + // + }, + css: { + // + }, + config: { + // + } + }, +}) +``` + +#### `integrations` + +Integrations control which other modules this module should enable and setup from the list below. Disabling them allows you to remove them, or gives you the option to set them up yourself. + +- **meta** + + Default: `true` + Disable to take full control of meta tags. + +- **pwa** + + Default: `true` + Disable to take full control of icon generation, manifest and service worker installation. + +- **router** + + Default: `true` + Disable to configure Ionic Router yourself. + +- **icons** + + Default: `true` + Disable to stop icons from being auto-imported. + +#### `css` + +Configure which Ionic stylesheets are automatically added to your application. For more information about +these stylesheets, [see the Ionic Documentation for Stylesheets](https://ionicframework.com/docs/layout/global-stylesheets). + +- **core** + + Default: `true` + Disable to import these CSS files manually: + + - `@ionic/vue/css/core.css` + +- **basic** + + Default: `true` + Disable to import these CSS files manually: + + - `@ionic/vue/css/normalize.css` + - `@ionic/vue/css/structure.css` + - `@ionic/vue/css/typography.css` + +- **utilities** + + Default: `false` + Enable to add extra Ionic CSS utilities: + + - `@ionic/vue/css/padding.css` + - `@ionic/vue/css/float-elements.css` + - `@ionic/vue/css/text-alignment.css` + - `@ionic/vue/css/text-transformation.css` + - `@ionic/vue/css/flex-utils.css` + - `@ionic/vue/css/display.css` + +#### `config` + +Configure Ionic components globally across your app, such as app mode, tab button layout, etc. For example: + +```js [nuxt.config.ts] +export default defineNuxtConfig({ + ionic: { + config: { + rippleEffect: false, + mode: 'md', + // ... + }, + }, +}) +``` + +::alert{type="info"} +Please see the [Ionic Config Options](https://ionicframework.com/docs/vue/config#config-options) for available keys, values +and examples of how they work. +:: + +### Capacitor Config + +Capacitor is configured via the `capacitor.config.ts` file - this is only required if you are targeting native devices such as iOS or Android. + +::alert{type="info"} +Please see the [Capacitor Config docs](https://capacitorjs.com/docs/config) for more information. +:: diff --git a/docs/content/1.get-started/4.enabling-capacitor.md b/docs/content/1.get-started/4.enabling-capacitor.md new file mode 100644 index 00000000..81ccd8de --- /dev/null +++ b/docs/content/1.get-started/4.enabling-capacitor.md @@ -0,0 +1,70 @@ +--- +navigation.icon: nonicons:capacitor-16 +--- + +# Enabling Capacitor + +[Capacitor](https://capacitorjs.com/) is a powerful tool for shipping to native platforms like iOS and Android, separate from or alongside your web app. + +The good news is that it's installed by default with `@nuxtjs/ionic`. You just need to enable it in your ionic app, and choose what platforms you want to support. + +> The Ionic CLI is available via `npx` or can be installed globally with `npm install -g @ionic/cli` or `yarn global add @ionic/cli` or `pnpm add -g @ionic/cli`. + +::code-group + +```bash [npx] +npx @ionic/cli integrations enable capacitor +npx @ionic/cli capacitor add ios +npx @ionic/cli capacitor add android +``` + +```bash [npm] +# ionic config set -g npmClient npm + +ionic integrations enable capacitor +ionic capacitor add ios +ionic capacitor add android +``` + +```bash [yarn] +ionic config set -g npmClient yarn + +ionic integrations enable capacitor +ionic capacitor add ios +ionic capacitor add android +``` + +```bash [pnpm] +ionic config set -g npmClient pnpm + +ionic integrations enable capacitor +ionic capacitor add ios +ionic capacitor add android +``` + +:: + +::alert{type="info"} +Read more about [creating for iOS and Android here](/cookbook/creating-ios-android-apps). +:: + +#### Run on iOS or Android + +Once an Android or iOS project is added with Capacitor, you can run your app on an iOS or Android emulator. + +::alert +Android Studio and SDK (for Android projects) or XCode (for iOS projects) are required to use the `npx cap open` or `npx cap run` command. See the [Capacitor Environment Setup docs](https://capacitorjs.com/docs/getting-started/environment-setup) for details. +:: + +To build, sync, and run your app: + +1. Create a web build with `npx nuxi generate` or `npx nuxi build`. +2. Run `npx cap sync` to update your Capacitor project directories with your latest app build. +3. Run `npx cap run android` or `npx cap run ios` to run the app from the command line using an installed device **OR** +4. _(Optional)_ Run `npx cap open android` or `npx cap open ios` to open the project in Android Studio or XCode, respectively. + +> Remember to run `npx cap sync` after every new build to ensure your Android and/or iOS project is up-to-date. + +::alert{type="info"} +Read more about [local development for iOS and Android here](/cookbook/local-development). +:: diff --git a/docs/content/1.get-started/5.watch-outs.md b/docs/content/1.get-started/5.watch-outs.md new file mode 100644 index 00000000..1bf0b0fc --- /dev/null +++ b/docs/content/1.get-started/5.watch-outs.md @@ -0,0 +1,72 @@ +--- +navigation.icon: uil:exclamation-triangle +--- + +# Watchouts + +This page aims to succinctly mention things to watch out for when building your Nuxt-powered Ionic application, particularly for those familiar with regular Nuxt and Vue applications. + +## Pages and Navigation + +::list{type="warning"} +- Avoid using ``, `` or ``. These are currently not integrated with this module. +:: + +Instead, Ionic expects `` to show the route component, and `useIonRouter()` or the `router-link` property on any `ion-` component to change page. + +```vue [app.vue] + +``` + +::list{type="warning"} +- The root element of every page must always be ``. +:: + +This is required by Ionic to set up page transitions and stack navigation. Each view that is navigated to using the router must include an component. + +::list{type="warning"} +- When navigating from a tabbed route to a non-tabbed route, `route.params` from the auto-imported `useRoute()` will always be an empty object. +:: + +A current workaround is to `import { useRoute } from 'vue-router';`. + +::alert{type="info"} +Read more [about routing here](/overview/routing). +:: + +## Lifecycle Hooks + +Ionic handles lifecycle events slightly differently to Vue, as it persists some components in the DOM when Vue would usually unmount them. + +This means the various mounted hooks, e.g. `onBeforeMount`, may not be called when you would expect them to. + +To help with this, Ionic has added extra lifecycle hooks which behave how you may have expected the mounted hooks to behave. + +::alert{type="info"} +Read about the [Ionic Vue lifecycle hooks here](https://ionicframework.com/docs/vue/lifecycle). +:: + +Because of this, some expected functionality from Nuxt or other modules may not work or may require changes to get functioning: + +::list{type="warning"} +- **The composable `useHead()` will not work out of the box**. + See [our cookbook page](/cookbook/page-metadata) for how to continue using `useHead()` +- **Certain Vue Router components should not be used**. + This includes ``, ``, and `` - [read more here](https://ionicframework.com/docs/vue/lifecycle#how-ionic-framework-handles-the-life-of-a-page). +:: + +## No serverside rendering + +::list{type="warning"} +- The application code cannot contain any serverside rendering. +:: + +When targeting iOS or Android devices, the build must be able to run completely on the clientside. We discuss [solutions for if you're targeting both web and device here](/cookbook/web-and-device). + +::alert{type="info"} +Learn more about [building for native devices here](/cookbook/creating-ios-android-apps). +:: diff --git a/docs/content/1.get-started/_dir.yml b/docs/content/1.get-started/_dir.yml new file mode 100644 index 00000000..10925bfb --- /dev/null +++ b/docs/content/1.get-started/_dir.yml @@ -0,0 +1,2 @@ +icon: heroicons-outline:star +navigation.redirect: /get-started/introduction diff --git a/docs/content/2.getting-started.md b/docs/content/2.getting-started.md deleted file mode 100644 index 8e679914..00000000 --- a/docs/content/2.getting-started.md +++ /dev/null @@ -1,163 +0,0 @@ ---- -title: Getting started -description: 'Download & install Ionic and setup Capacitor for usage' ---- - -## Installation - -Add `@nuxtjs/ionic` to your project's dev dependencies: - -::code-group - -```bash [yarn] -yarn add --dev @nuxtjs/ionic -``` - -```bash [npm] -npm install @nuxtjs/ionic -D -``` - -```bash [pnpm] -pnpm install @nuxtjs/ionic -D -``` - -:: - -Then add the module to your Nuxt configuration: - -```js{}[nuxt.config] -export default defineNuxtConfig({ - modules: ['@nuxtjs/ionic'] -}) -``` - -Finally, either remove your `app.vue` file or replace it with a custom one (starting with [this template](/features#advanced)). - -You're good to go! - -::alert{type=info} -The first time you start a Nuxt project with `@nuxtjs/ionic` enabled, a `ionic.config.json` file will be created if it doesn't already exist. -:: - -## Enabling Capacitor - -[Capacitor](https://capacitorjs.com/) is a powerful tool for shipping to native platforms like iOS and Android alongside your web app. - -The good news is that it's installed by default with `@nuxtjs/ionic`, but you will need to enable it and choose what platforms you want to support. - -> The Ionic CLI is available via `npx` or can be installed globally with `npm install -g @ionic/cli` or `yarn global add @ionic/cli` or `pnpm add -g @ionic/cli`. - -::code-group - -```bash [npx] -npx @ionic/cli integrations enable capacitor -npx @ionic/cli capacitor add ios -npx @ionic/cli capacitor add android -``` - -```bash [npm] -# ionic config set -g npmClient npm - -ionic integrations enable capacitor -ionic capacitor add ios -ionic capacitor add android -``` - -```bash [yarn] -ionic config set -g npmClient yarn - -ionic integrations enable capacitor -ionic capacitor add ios -ionic capacitor add android -``` - -```bash [pnpm] -ionic config set -g npmClient pnpm - -ionic integrations enable capacitor -ionic capacitor add ios -ionic capacitor add android -``` - -:: - -### Run on iOS or Android - -Once an Android or iOS project is added with Capacitor, you can run your app on an iOS or Android emulator. - -::alert -Android Studio and SDK (for Android projects) or XCode (for iOS projects) are required to use the `npx cap open` or `npx cap run` command. See the [Capacitor Environment Setup docs](https://capacitorjs.com/docs/getting-started/environment-setup) for details. -:: - -To build, sync, and run your app: - -1. Create a web build with `npx nuxi generate` or `npx nuxi build`. -2. Run `npx cap sync` to update your Capacitor project directories with your latest app build. -3. Run `npx cap run android` or `npx cap run ios` to run the app from the command line using an installed device **OR** -4. _(Optional)_ Run `npx cap open android` or `npx cap open ios` to open the project in Android Studio or XCode, respectively. - -> Remember to run `npx cap sync` after every new build to ensure your Android and/or iOS project is up-to-date. - -## Options - -While not required, you can configure the features that are enabled: - -```js -export default defineNuxtConfig({ - modules: ['@nuxtjs/ionic'], - ionic: { - integrations: { - // - }, - css: { - // - }, - config: { - // - } - }, -}) -``` - -### `integrations` - -- **meta** - - Default: `true` - Disable to take full control of meta tags. - -- **pwa** - - Default: `true` - Disable to take full control of icon generation, manifest and service worker installation. - -- **router** - - Default: `true` - Disable to configure Ionic Router yourself. - -- **icons** - - Default: `true` - Disable to stop icons from being auto-imported. - -### `css` - -- **core** - - Default: `true` - Disable to import these CSS files manually. - -- **basic** - - Default: `true` - Disable to import these CSS files manually. - -- **utilities** - - Default: `false` - Enable to add extra Ionic CSS utilities. - -### `config` - -- See [Config Options](https://ionicframework.com/docs/vue/config#config-options) diff --git a/docs/content/2.overview/1.routing.md b/docs/content/2.overview/1.routing.md new file mode 100644 index 00000000..d6bf0b6e --- /dev/null +++ b/docs/content/2.overview/1.routing.md @@ -0,0 +1,179 @@ +--- +navigation.icon: uil:sign-alt +--- + +# Routing + +Routing within your Nuxt Ionic application will feel very similar, but with a couple of differences. + +By default, this module sets up the Ionic Router, or `IonRouter`. This router is built on top of `vue-router`, but with some changed functionality specifically for making it work better for mobile applications. + +::list{type="success"} +- Enables [non-linear routing](https://ionicframework.com/docs/vue/navigation#non-linear-routing), e.g. for application tabs +- Separate navigation stacks for each tab of your application +- Rich page transitions out-of-the-box, appropriate for mobile +- Simple API for custom animations and direction control when navigating via links +:: + +## Pages + +Just like regular Nuxt, you can start building your Ionic application by creating routes within the `~/pages` directory. Every Vue file inside this directory will generate a route that displays the contents of the file. Read more about [Nuxt file-based routing](https://nuxt.com/docs/getting-started/routing) here. + +::list{type="warning"} +- The root component of every page must always be the `` component. +:: + +This is required by Ionic to set up page transitions and stack navigation. Each view that is navigated to using the router must include an `` component. + +```vue [~/pages/home.vue] + +``` + +::alert{type="info"} +Read more about [`` here](https://ionicframework.com/docs/vue/navigation#ionpage). +:: + +### Defining page meta + +Nuxt utilities like `definePageMeta` are fully functional. However, you should avoid using `` or `` as these will not function correctly, due to Ionic requiring an `` instead. + +::alert{type="info"} +Read more about [`definePageMeta` here](https://nuxt.com/docs/api/utils/define-page-meta). +:: + +### Define a root alias if there's no index.vue page + +Usually applications with tab bars will not have a `~/pages/index.vue` file, as it's not needed. However, this will mean opening the app will return a 404, e.g. on localhost:3000. + +To solve this, if you do not have a `~/pages/index.vue` file in your project, you should add the following code to the page that you want to be displayed on your app's root page: + +```ts [pages/tabs.vue] +definePageMeta({ + alias: ['/'], +}) +``` + +It will now be used as the root path, and will be routed to by default when visiting e.g. localhost:3000. + + +## Navigation + +Navigation can be done in several ways, using the `IonRouter` or certain `ion-` components. + +::alert{type="info"} +Read about navigation in [Ionic's Vue Navigation docs](https://ionicframework.com/docs/vue/navigation). +:: + +### IonRouter + +To access the router, use the composable `useIonRouter()`. This should always be used instead of the regular `useRouter()` (which is auto-imported from `vue-router` by Nuxt). This ensures the benefits of the Ion Router are always provided. + +This module auto-imports `useIonRouter()` so it should be available automatically. If this is disabled, you can import it from `@ionic/vue`. + +It is best used when you wish to control navigation programmatically and have full control over the page transitions. + +```vue + +``` + +::alert{type="info"} +Read more about [`useIonRouter() here`](https://ionicframework.com/docs/vue/navigation#navigating-using-useionrouter). +:: + +### Navigating with Components + +All Ionic components expose a `router-link` attribute. When set, the router will navigate to the specified route when the component is clicked. It accepts strings as well as named routes. + +`router-direction` and `router-animation` are also available for further control. + +It's best used when simple routing is required, without any programmatic logic before or after. + +```vue + +``` + + +::alert{type="info"} +Read about [using the `router-link` attribute here](https://ionicframework.com/docs/vue/navigation#navigating-using-router-link). +:: + +::alert{type="warning"} +Avoid using `` for now as it currently is not integrated with the Ionic Router. +:: + +## Route Parameters + +When accessing route parameters, `useRoute()` should continue to be used, just like regular Nuxt. + +```vue [pages/posts/[id}.vue] + +``` + +::alert{type="info"} +Read more about [Nuxt route parmeters here](https://nuxt.com/docs/getting-started/routing#route-parameters). +:: + +## Route Middleware + +Nuxt's Route Middleware is also integrated and available, just like regular Nuxt. + +::code-group + +```ts [middleware/auth.ts] +export default defineNuxtRouteMiddleware((to, from) => { + // isAuthenticated() is an example method verifying if a user is authenticated + if (isAuthenticated() === false) { + return showLoginModal(); // showLoginModal() is an example of opening a modal flow for authentication + } +}) +``` + +```html [pages/tabs/feed.vue] + + + +``` + +:: + +::alert{type="info"} +Read more about [Nuxt route middleware here](https://nuxt.com/docs/getting-started/routing#route-middleware). +:: diff --git a/docs/content/2.overview/2.theming.md b/docs/content/2.overview/2.theming.md new file mode 100644 index 00000000..ae231386 --- /dev/null +++ b/docs/content/2.overview/2.theming.md @@ -0,0 +1,34 @@ +--- +navigation.icon: uil:palette +--- + +# Theming + +Ionic provides many css variables with which their components derive css styles. These variables can be overridden to customise the theme of your app. + +In its most simple form, you can create a `~/assets/css/ionic.css` file and add it to the `css` property in your `nuxt.config.ts` file. You can then add css variables that you'd like to override within this file, under the `:root` selector: + +::code-group + +```css [assets/css/ionic.css] +:root { + --ion-color-primary: #57e389; + --ion-color-primary-rgb: 87, 227, 137; + --ion-color-primary-contrast: #000000; + --ion-color-primary-contrast-rgb: 0, 0, 0; + --ion-color-primary-shade: #4dc879; + --ion-color-primary-tint: #68e695; + + /* And so on... */ +} +``` + +```ts [nuxt.config.ts] +export default defineNuxtConfig({ + css: ['~/assets/css/ionic.css'], +}) +``` + +:: + +To learn more about theming and which variables to override, check out Ionic's [official theming documentation](https://ionicframework.com/docs/theming/basics). diff --git a/docs/content/2.overview/3.ionic-auto-imports.md b/docs/content/2.overview/3.ionic-auto-imports.md new file mode 100644 index 00000000..aafe6da8 --- /dev/null +++ b/docs/content/2.overview/3.ionic-auto-imports.md @@ -0,0 +1,48 @@ +--- +navigation.icon: uil:channel +--- + +# Ionic Auto-Imports + +Ionic provides various components and helper functions for use in your application. + +This module automatically auto-imports them throughout your app, so you do not need to import them manually. + +::alert{type="info"} +Read more about [how component auto-imports work](https://v3.nuxtjs.org/guide/directory-structure/components#components-directory). +:: + +## Ionic Components + +All Ionic Vue components should be auto-imported throughout your app. Although your IDE should be aware of these components everywhere, they are not globally registered and are only imported within the components that use them. + +For a list of all Ionic Vue components, please refer to the ionic component documentation: https://ionicframework.com/docs/components + +::alert{type="info"} +If you find a component that isn't being auto-imported, please [open an issue](https://github.com/nuxt-modules/ionic/issues/new/choose) or [a pull request](https://github.com/nuxt-modules/ionic/compare). +:: + +## Ionic Helper Functions + +A number of Ionic hooks/composables are also imported by Nuxt via auto-imports within your app: + +- [`getPlatforms`](https://ionicframework.com/docs/vue/platform#getplatforms) +- [`isPlatform`](https://ionicframework.com/docs/vue/platform#isplatform) +- [`menuController`](https://ionicframework.com/docs/api/menu) +- [`onIonViewWillEnter`](https://ionicframework.com/docs/vue/lifecycle#ionic-framework-lifecycle-methods) +- [`onIonViewDidEnter`](https://ionicframework.com/docs/vue/lifecycle#ionic-framework-lifecycle-methods) +- [`onIonViewWillLeave`](https://ionicframework.com/docs/vue/lifecycle#ionic-framework-lifecycle-methods) +- [`onIonViewDidLeave`](https://ionicframework.com/docs/vue/lifecycle#ionic-framework-lifecycle-methods) +- [`useBackButton`](https://ionicframework.com/docs/vue/utility-functions#hardware-back-button) +- [`useKeyboard`](https://ionicframework.com/docs/vue/utility-functions#keyboard) +- [`useIonRouter`](https://ionicframework.com/docs/vue/utility-functions#router) +- [`createAnimation`](https://ionicframework.com/docs/utilities/animations) +- [`createGesture`](https://ionicframework.com/docs/utilities/gestures) +- [`getTimeGivenProgression`](https://github.com/ionic-team/ionic-framework/blob/main/core/src/utils/animation/cubic-bezier.ts#L20) +- [`iosTransitionAnimation`](https://github.com/ionic-team/ionic-framework/blob/main/core/src/utils/transition/ios.transition.ts#L267) +- [`mdTransitionAnimation`](https://github.com/ionic-team/ionic-framework/blob/main/core/src/utils/transition/md.transition.ts#L6) + +::alert{type="info"} +Read more about these [helper functions in Ionic's docs](https://ionicframework.com/docs/). +:: + diff --git a/docs/content/2.overview/4.module-utilities.md b/docs/content/2.overview/4.module-utilities.md new file mode 100644 index 00000000..f93b7a96 --- /dev/null +++ b/docs/content/2.overview/4.module-utilities.md @@ -0,0 +1,64 @@ +--- +navigation.icon: uil:layer-group +--- + +# Module Utilities + +This modules aims to provide a few components and helpers for an easier and more seamless integration of Ionic's composables or functions in your app. We currently have the one `IonAnimation` component. + +## Components + +### `IonAnimation` component + +This component makes using Ionic's `createAnimation` easier. It matches the majority of props directly to the usual Ionic animation object, to make adoption easier. + +For more information, see [official Ionic docs](https://ionicframework.com/docs/utilities/animations) or check out the [playground examples](https://github.com/nuxt-modules/ionic/blob/main/playground/pages/tabs/tab4.vue) + +You can see how it replaces usage of the regular [`createAnimation`](https://ionicframework.com/docs/utilities/animations#installation) function in the code example below: + +::code-group + +```vue [IonAnimation] + +``` + +```vue [Manual usage] + +``` + +:: + +::alert{type=info} +Currently component doesn't support grouped and chained animations. For that usage we still recommend using `createAnimation` by itself +:: diff --git a/docs/content/2.overview/5.icons.md b/docs/content/2.overview/5.icons.md new file mode 100644 index 00000000..2697f12c --- /dev/null +++ b/docs/content/2.overview/5.icons.md @@ -0,0 +1,41 @@ +--- +navigation.icon: uil:illustration +--- + +# Icons + +Icons are auto-imported from [`ionicons/icons`](https://github.com/ionic-team/ionicons) by default, following the pattern of camel case naming with `ionicons` in front of the original icon name, that you can find on the [official ionicons website](https://ionic.io/ionicons). + +::code-group + +```vue [Auto-imported icons] + +``` + +```vue [Manual imports] + + + +``` + +:: + +You can opt-out of auto-importing icons by setting the `integrations.icons` module options in your `nuxt.config.ts` to `false`. + +```js +export default defineNuxtConfig({ + ionic: { + integrations: { + icons: false, + }, + }, +}) +``` diff --git a/docs/content/2.overview/6.deployment.md b/docs/content/2.overview/6.deployment.md new file mode 100644 index 00000000..66c11215 --- /dev/null +++ b/docs/content/2.overview/6.deployment.md @@ -0,0 +1,26 @@ +--- +navigation.icon: uil:rocket +--- + +# Deployment + +## Web + +Deployment on the web is the same as any Nuxt project. You can find more information for this in Nuxt's deployment documentation. + +::alert{type="info"} +Read more about [deploying to the web](https://nuxt.com/docs/getting-started/deployment). +:: + + +## iOS and Android + +For iOS and Android, it's a little more involved. We recommend looking at the deployment documentation from Ionic for these platforms: + +### iOS + +https://ionicframework.com/docs/deployment/app-store + +### Android + +https://ionicframework.com/docs/deployment/play-store diff --git a/docs/content/2.overview/_dir.yml b/docs/content/2.overview/_dir.yml new file mode 100644 index 00000000..9b46d1d4 --- /dev/null +++ b/docs/content/2.overview/_dir.yml @@ -0,0 +1,2 @@ +icon: heroicons-outline:sparkles +navigation.redirect: /overview/routing diff --git a/docs/content/3.cookbook/1.customising-app-vue.md b/docs/content/3.cookbook/1.customising-app-vue.md new file mode 100644 index 00000000..5aa59107 --- /dev/null +++ b/docs/content/3.cookbook/1.customising-app-vue.md @@ -0,0 +1,32 @@ +--- +title: Customising app.vue +--- + +# Customising `app.vue` + +This module provides a default `app.vue` file for when one is not otherwise provided by your app. + +If you need to customize this `app.vue` file, you can create a new one in your project's source directory, based off the default: + +```vue [app.vue] + +``` + +This module will then stop providing one, so that your project's `app.vue` is used instead. + +## Necessary ion tags + +It's necessary that `` and `` are provided in your `app.vue` for Ionic to function. + +`` is the container element of Ionic - there should be only one per project - and is required for certain behaviours to work. Please see the [Ionic ion-app documentation](https://ionicframework.com/docs/api/app) for more info. + +Equally, `` provides a mounting point for the route component. In regular Nuxt applications, +this would be ``, but as Ionic Router is handling our routing we must use the ``. + +::alert{type="warning"} +Remember that app.vue acts as the main component of your Nuxt application. Anything you add to it (JS and CSS) will be global and included in every page. Read more about app.vue [in the Nuxt app.vue docs](https://nuxt.com/docs/guide/directory-structure/app). +:: diff --git a/docs/content/3.cookbook/2.local-development.md b/docs/content/3.cookbook/2.local-development.md new file mode 100644 index 00000000..29327944 --- /dev/null +++ b/docs/content/3.cookbook/2.local-development.md @@ -0,0 +1,145 @@ +# Local Development + +::alert{type="info"} +You may find the Ionic docs on developing [for iOS](https://ionicframework.com/docs/developing/ios) and [for Android](https://ionicframework.com/docs/developing/android) helpful before continuing. +:: + +When using Ionic just for the web, local development is as easy as running the `dev` script provided by Nuxt: + +::code-group + +```bash [yarn] +yarn dev -o +``` + +```bash [npm] +npm run dev -- -o +``` + +```bash [pnpm] +pnpm dev -o +``` + +:: + + +But when working with iOS and Android, we're required to sync our built project to XCode and Android Studio, [using `npx cap sync`](https://capacitorjs.com/docs/cli/commands/sync). + +This manual process can be tedious, but capacitor provides a way to livereload in development mode. This allows you to test on a native device or a device simulator and maintain the hot module replacement or livereload functionality that you enjoy already with Nuxt on the web. + +## Native device or simulator + +First, ensure your Nuxt development build is created and the development server is running: + +::code-group + +```bash [yarn] +yarn dev -o +``` + +```bash [npm] +npm run dev -- -o +``` + +```bash [pnpm] +pnpm dev -o +``` + +:: + +Then, in a separate tab, [sync the build](https://ionicframework.com/docs/cli/commands/capacitor-sync) to ios or android, based on the device you wish to run it on (or both). This copies the web build and capacitor configuration file into the native platform project, then updates the native plugins referenced in `package.json`, and installs any discovered capacitor or cordova plugins. + +::code-group + +```bash [ios] +npx @ionic/cli capacitor sync ios --no-build +``` + +```bash [android] +npx @ionic/cli capacitor sync android --no-build +``` + +:: + +Then to deploy this to a native device or device simulator with livereload, you can [ask Capacitor to run the build](https://ionicframework.com/docs/cli/commands/capacitor-run). Ensure your native device is plugged in so that it displays in your list. + +::code-group + +```bash [ios] +npx @ionic/cli capacitor run ios --livereload-url=http://${LIP}:3000 --external --mode development +``` + +```bash [android] +npx @ionic/cli capacitor run android --livereload-url=http://${LIP}:3000 --external --mode development +``` + +:: + +The app will then open on the chosen native device or device simulator. + +## Automating on-device dev + +We recommend putting this into a script in `scripts/` that you can run more easily via `yarn run` or `pnpm run`. For example: + +::code-group + +```bash [scripts/android.sh] +#!/bin/bash +LIP=$(ipconfig getifaddr en0) + +echo "🍦 Starting local development to android device - ensure local dev server is running already" +echo "🏗️ Type checking and building for development..." +pnpm run build:dev +echo "🔃 Capacitor installation, podfile installation, sync and copy to app distribution folders..." +npx @ionic/cli capacitor sync android --no-build +echo "🏃 Select an Android device to run the build at local ip address ${LIP} on..." +eval "npx @ionic/cli capacitor run android --livereload-url=http://${LIP}:3000 --external --mode development" +``` + +```bash [scripts/ios.sh] +#!/bin/bash +LIP=$(ipconfig getifaddr en0) + +echo "🍦 Starting local development to ios device - ensure local dev server is running already" +echo "🏗️ Type checking and building for development..." +pnpm run build:dev +echo "🔃 Capacitor installation, podfile installation, sync and copy to app distribution folders..." +npx @ionic/cli capacitor sync ios --no-build +echo "🏃 Select an iOS device to run the build at local ip address ${LIP} on..." +eval "npx @ionic/cli capacitor run ios --livereload-url=http://${LIP}:3000 --external --mode development" +``` + +:: + +```json [package.json] +{ + "scripts": { + "android": "bash ./scripts/android.sh", + "ios": "bash ./scripts/ios.sh" + } +} +``` + +::code-group + +```bash [yarn] +yarn ios +yarn android +``` + +```bash [npm] +npm run ios +npm run android +``` + +```bash [pnpm] +pnpm run ios +pnpm run android +``` + +:: + + +::alert{type="warning"} +If you're having trouble with this step, please check the Ionic guides for [deploying to iOS](https://ionicframework.com/docs/developing/ios) and [deploying to android](https://ionicframework.com/docs/developing/android) for more information. +:: diff --git a/docs/content/3.cookbook/3.app-tabs.md b/docs/content/3.cookbook/3.app-tabs.md new file mode 100644 index 00000000..ed100a50 --- /dev/null +++ b/docs/content/3.cookbook/3.app-tabs.md @@ -0,0 +1,208 @@ +--- +title: App Tabs +--- + +# App Tabs + +It's common for mobile apps to come with tabs at the bottom of the screen. These tabs act as separate routing stacks, so should remember where they were when a user navigates away and back to a tab. + +Ionic provides several components to provide App Tabs out of the box, with a deep integration with the Ionic Router for them. + +::alert{type="info"} +Read more about [Ionic's `ion-tabs` here](https://ionicframework.com/docs/api/tabs). +:: + +## Setup an application with tabs + +> See the example in [the playground](https://github.com/nuxt-modules/ionic/blob/main/playground) for a working demo of an app with tabs. + +Tabs require a main tab component, and then child components to be rendered in the tab view. + +Your file structure should look like this: + +```text [pages/ directory] +pages/ +--| tabs.vue +--| tabs/ +----| tab1.vue +----| tab2.vue +----| tab3.vue +----| tab4.vue +``` + +These tabs should then have a similar code structure as shown below. Remember, all pages must start with an `ion-page` component. + +::code-group + +```vue [pages/tabs.vue] + +``` + +```vue [pages/tabs/tab1.vue] + +``` + +```vue [pages/tabs/tab2.vue] + +``` + +:: + + +All pages that should show inside these tabs must be **sibling routes** of these initial tab views, but with the name of the tab in its prefix. + +The simplest way to manage this is for all pages being within this `pages/tabs/` directory, with a directory per tab, like so: + +```text [pages/ directory] +pages/ +--| tabs.vue +--| tabs/ +----| tab1/ +------| index.vue +------| a-page.vue +----| tab2/ +------| index.vue +----| tab3/ +------| index.vue +----| tab4.vue +------| index.vue +------| another-page.vue +``` + +If a particular tab only has one route component, you don't explicitly need the directory for it with the index.vue inside +of it, but we find it's a neater approach this way. + +Using these directories avoids the routes becoming children routes of the tab by accident. The following folder structure is incorrect and would result in children routes, which IonRouter will not serve correctly: + +::list{type="danger"} +- An example of incorrect routing (do not copy): +:: + +```text [pages/ directory] +pages/ +--| tabs.vue +--| tabs/ +----| tab1.vue +----| tab1/ +------| a-page.vue +----| tab2.vue +----| tab3.vue +----| tab4.vue +----| tab4/ +------| another-page.vue +``` + +::alert{type="success"} +Ionic provides an article on [best practices for using tabs in your application](https://ionicframework.com/docs/vue/navigation#working-with-tabs). +:: + +## Routing to pages that shouldn't be displayed in the tabs + +If you'd like to surface a page on-top of the tabs, rather than inside one of them, you can include the page component outside +of the tabs directory. + +```text [pages/ directory] +pages/ +--| tabs.vue +--| tabs/ +----| tab1/ +------| index.vue +------| a-page.vue +----| tab2/ +------| index.vue +--| settings.vue +``` + +::list{type="danger"} +- When navigating from a tabbed route to a non-tabbed route, `route.params` from the auto-imported `useRoute()` will always be an empty object. A current workaround is to `import { useRoute } from 'vue-router';`. +:: + +## Reusing views across tabs + +Some apps may require showing the same component in different tabs. For instance, Spotify will allow you to view an album from both the Home and the Search tab. + +To best accomplish this with Nuxt's file-based routing, create the routes using vue components in `pages/tabs`, and have them include the same component. + +::code-group +```text [pages/ directory] +pages/ +--| tabs.vue +--| tabs/ +----| home/ +------| index.vue +------| album-[id].vue +----| search/ +------| index.vue +------| album.vue +----| library/ +------| index.vue +``` + +```vue [pages/home/album-{id}.vue] + +``` + +```vue [pages/search/album-{id}.vue] + +``` +:: + +::alert{type="info"} +Read more about [reusing views across tabs in the Ionic docs](https://ionicframework.com/docs/vue/navigation#switching-between-tabs). +:: diff --git a/docs/content/3.cookbook/4.page-metadata.md b/docs/content/3.cookbook/4.page-metadata.md new file mode 100644 index 00000000..beaab618 --- /dev/null +++ b/docs/content/3.cookbook/4.page-metadata.md @@ -0,0 +1,15 @@ +--- +title: useHead / Page Meta +--- + +# `useHead` / Page Meta + +::alert{type="warning"} +⚠️ This page is a stub and needs further information. +:: + +The composable `useHead()` will not work out of the box. + +Please see this issue for reference: https://github.com/nuxt-modules/ionic/issues/6 + +Also see the documentation for use-head: https://nuxt.com/docs/api/composables/use-head diff --git a/docs/content/3.cookbook/5.creating-ios-android-apps.md b/docs/content/3.cookbook/5.creating-ios-android-apps.md new file mode 100644 index 00000000..776f9656 --- /dev/null +++ b/docs/content/3.cookbook/5.creating-ios-android-apps.md @@ -0,0 +1,27 @@ +--- +title: iOS and Android Apps +--- + +# Creating iOS and Android Apps + +::alert{type="warning"} +⚠️ This page is a stub and needs further information. +:: + +When building for iOS and Android, we recommend setting `ssr: false` in your nuxt config + +```js [nuxt.config.ts] +export default defineNuxtConfig({ + modules: ['@nuxtjs/ionic'], + ssr: false, +}) +``` + +Also see: + +- https://ionicframework.com/docs/developing/ios +- https://ionicframework.com/docs/developing/android +- https://ionicframework.com/docs/deployment/app-store +- https://ionicframework.com/docs/deployment/play-store + +Please also see our page on (building for both Web and Device together)(/cookbook/web-and-device) diff --git a/docs/content/3.cookbook/6.web-and-device.md b/docs/content/3.cookbook/6.web-and-device.md new file mode 100644 index 00000000..98087967 --- /dev/null +++ b/docs/content/3.cookbook/6.web-and-device.md @@ -0,0 +1,59 @@ +# Deploying to both Web and Device + +Here we talk a little about some differences in deploying to native devices over the web, and what is required from the codebase to do so. We then explore some potential solutions to solve these issues. + +## Building for native devices + +One main caveat of building for native devices is that the final build needs to be able to run completely +clientside. Another is that deploying a new build requires submitting to the app stores and being manually reviewed and approved. + +This makes building for devices more cumbersome than deploying to the web, and means the following must be followed when deploying: + +::list{type=danger} +- **No serverside rendering in the codebase** + As the build must be able to run completely clientside, we cannot have serverside rendering in the codebase. + +- **Generating new builds are not quickly deployed** + A common paradigm on the web is to use serverside generation to build an app from stable data, then push the bundle to the web. This is then re-generated based on CMS changes or other triggers to ensure a static site that can stay up-to-date. + + As deploying to the app stores is much slower than to the web, this approach likely will not work anymore. +:: + +This means, in the codebase that will be deployed to the devices, we recommend using `ssr: false`, and not using serverside rendering at all. + +If serverside rendering is required on the web, the simplest solution is to create two Nuxt projects: one targeting the web with SSR/SSG, and one targeting devices. + +## Further Solutions + +Having two completely separate codebases to target web and device is a little cumbersome, so there are some potential solutions you could explore. + +These solutions are outside of the scope of this module, but are provided as guidance on improving your own DX in these cases. We'd love to hear about if you implement these successfully. + +### A single codebase + +It may be possible to have a single codebase with both SSR and a fully static application in-tandem, with code-switching based on configuration. E.G. when building for the web, setting `ssr: true`, and when building for devices, setting `ssr: false`. + +You may need further wrapping around other SSR-aware code and utilities, such as `useAsyncData()`. + +### A monorepo + +You would likely be able to reduce the burden of two separate Nuxt apps by utilising a monorepo. The majority of your shared code could exist within a core package, while having two Nuxt apps, one to target Web with `ssr: true` and one to target devices with `ssr: false`. + +A possible directory structure for this may look like: + +``` +- apps + - nuxt-web + - ... + - nuxt.config.ts + - nuxt-device + - ... + - nuxt.config.ts +- packages + - core + - components + - composables + - ... +``` + + diff --git a/docs/content/3.cookbook/_dir.yml b/docs/content/3.cookbook/_dir.yml new file mode 100644 index 00000000..00491074 --- /dev/null +++ b/docs/content/3.cookbook/_dir.yml @@ -0,0 +1,2 @@ +icon: heroicons-outline:bookmark-alt +navigation.redirect: /cookbook/customising-app-vue diff --git a/docs/content/3.features.md b/docs/content/3.features.md deleted file mode 100644 index bd4829d5..00000000 --- a/docs/content/3.features.md +++ /dev/null @@ -1,171 +0,0 @@ ---- -title: Features -description: 'All the features this module offers for building apps with Ionic at great speed' ---- - -## Page routing - -Out of the box, you can start building your Ionic application by creating routes within `~/pages` directory. To access the router, you should use `useIonRouter()` rather than `useRouter()` (which is auto-imported from `vue-router`). - -Nuxt utilities like `definePageMeta` will continue to work, but you should avoid using `` or ``. - -::alert -The root component of every page should be the `` component. -:: - -::alert -If you do not have a `~/pages/index.vue` file in your project, you should add the following code to the page that you want to be displayed on your app's root page: - -```ts [pages/home.vue] -definePageMeta({ - alias: ['/'], -}) -``` - -:: - -## Theming the app - -To customize the theme of your app, you can override the Ionic's default css variables. You can start by creating a `~/assets/css/ionic.css` file and adding it to `css` property in your `nuxt.config.ts` file. Following the example: - -::code-group - -```ts [nuxt.config.ts] -export default defineNuxtConfig({ - css: ['~/assets/css/ionic.css'], -}) -``` - -```css [assets/css/ionic.css] -:root { - --ion-color-primary: #57e389; - --ion-color-primary-rgb: 87, 227, 137; - --ion-color-primary-contrast: #000000; - --ion-color-primary-contrast-rgb: 0, 0, 0; - --ion-color-primary-shade: #4dc879; - --ion-color-primary-tint: #68e695; - - /* And so on... */ -} -``` - -:: - -To learn more about theming and which variables to override, check out Ionic's [official theming documentation](https://ionicframework.com/docs/theming/basics). - -## Ionic Framework components - -All Ionic Vue components should be auto-imported throughout your app. (If you find one that isn't, please open an issue.) Although your IDE should be aware of these everywhere, they are not globally registered and are only imported within the components that use them. For more on how component imports work, see the [Nuxt documentation](https://v3.nuxtjs.org/guide/directory-structure/components#components-directory). - -::alert{type=info} -If you find a component that isn't being auto-imported, please open an issue or a pull request. If you're thinking of latter option, please do so in [alphabetical order](https://github.com/nuxt-modules/ionic/blob/main/src/module.ts#L188-L191) for making it easy for others to find the component as well! -:: - -## Module utility components - -Module also offers few components made for easier and more seamless way to integrate Ionic's composables or functions into your Nuxt app. - -### `IonAnimation` component - -Component made specifically to make usage of Ionic's `createAnimation` easier. It has almost 1 to 1 props matching as your usual animation object. For more see [official Ionic docs](https://ionicframework.com/docs/utilities/animations) or check out [playground examples](https://github.com/nuxt-modules/ionic/blob/main/playground/pages/tabs/tab4.vue) - -You can see how it replaces usage of regular `createAnimation` function in the code example below: - -::code-group - -```vue [IonAnimation] - -``` - -```vue [Manual usage] - -``` - -:: - -::alert{type=info} -Currently component doesn't support grouped and chained animations. For that usage we still recommend using `createAnimation` by itself -:: - -## Icons - -Icons are auto-imported from `ionicons/icons` by default, following the pattern of camel case naming with `ionicons` in front of the original icon name, that you can find on the [official ionicons website](https://ionic.io/ionicons). - -::code-group - -```vue [Auto-imported icons] - -``` - -```vue [Manual imports] - - - -``` - -:: - -You can opt-out of auto-importing by setting `integrations.icons` module options in your `nuxt.config.ts` to `false`. - -## Helper functions - -Nuxt provides a number of Ionic hooks/composables via auto-imports within your app: - -`createAnimation`, `createGesture`, `getPlatforms`, `getTimeGivenProgression`, `iosTransitionAnimation`, `isPlatform`, `mdTransitionAnimation`, `menuController`, `onIonViewWillEnter`, `onIonViewDidEnter`, `onIonViewWillLeave`, `onIonViewDidLeave`, `useBackButton`, `useKeyboard`, `useIonRouter` - -For more on what these do, you can read the [Ionic docs](https://ionicframework.com/docs/). For more on how auto-imports work, see the [Nuxt documentation](https://v3.nuxtjs.org/guide/concepts/auto-imports#auto-imports). - -## Advanced - -### Customizing your root `app.vue` - -If you need to customize the default Ionic `app.vue` file, you can create a new one in your project's source directory. - -This is the default: - -```vue [app.vue] - -``` diff --git a/playground/ionic.config.json b/playground/ionic.config.json index 9120ef04..4b825ec6 100644 --- a/playground/ionic.config.json +++ b/playground/ionic.config.json @@ -3,5 +3,5 @@ "integrations": { "capacitor": {} }, - "type": "vue" + "type": "vue-vite" } diff --git a/playground/pages/overlap.vue b/playground/pages/overlap.vue new file mode 100644 index 00000000..4935e1f7 --- /dev/null +++ b/playground/pages/overlap.vue @@ -0,0 +1,15 @@ + diff --git a/playground/pages/tabs/tab1.vue b/playground/pages/tabs/tab1/index.vue similarity index 100% rename from playground/pages/tabs/tab1.vue rename to playground/pages/tabs/tab1/index.vue diff --git a/playground/pages/tabs/tab2.vue b/playground/pages/tabs/tab2/index.vue similarity index 96% rename from playground/pages/tabs/tab2.vue rename to playground/pages/tabs/tab2/index.vue index 3f1e3b04..75b373af 100644 --- a/playground/pages/tabs/tab2.vue +++ b/playground/pages/tabs/tab2/index.vue @@ -1,6 +1,6 @@