April 13, 2023
  • All
  • Perspectives
  • Tutorials
  • Capacitor
  • Framework
  • PWA
  • Svelte

Cross-Platform Sveltekit & Capacitor Application: Yes It’s Possible!

Logan Brade

A common misconception is that Capacitor ONLY works if you have a React, Vue, or Angular app, but did you know that it works for other frameworks as well? I recently began my journey into learning Sveltekit and discovered that Sveltekit apps can use Capacitor as well as be deployed to iOS and Android just like those other frameworks. Let’s take a look at how you can use Svelte with Capacitor and create cross-platform apps like you can with React, Vue, or Angular. A demo of the project can be found on GitHub.

Sveltekit

What is Sveltekit? According to the Sveltekit website, it’s a UI framework that allows you to write concise components with HTML, CSS, and JavaScript built on Svelte and Vite. It’s a completely free open-source software that’s growing in popularity. While the Sveltekit team classifies it as a love letter to web development, I’ve recently discovered that it just might be crushing on cross-platform development with how easy it is to get it to work with Capacitor… (Don’t worry Sveltekit, your secret is safe with us).

Getting a Sveltekit project setup is incredibly simple. Just start with creating my-app:

npm create svelte@latest my-app

Select Skeleton Project and select Yes, using TypeScript syntax if you are using TypeScript:

When prompted for additional options, I selected Add ESLint for code linting but select the option that’s best for your project:

Once that is completed, we’ll need to go into the app directory and install all the boilerplate libraries:

cd my-app
npm install

Then open the project in your IDE of choice and run the project from the built-in terminal:

npm run dev -- --open

This should open up the application on http://localhost:5173/:

Capacitor

Once you have your Sveltekit project, we’ll need to get Capacitor running with the default Sveltekit project by installing @capacitor/core, @capacitor/cli, @capacitor/geolocation (we’ll be using geolocation later) and create the config (I’m using the default options so make sure you adjust these to work for your project as they’ll likely vary when/if you get to mobile deployments):

npm install @capacitor/core @capacitor/cli @capacitor/geolocation
npx cap init

Once installed, we’ll need to build the web app to compile everything:

npm run build

With the build completed, let’s test add a native Capacitor call to our Sveltekit project by updating src/routes/+page.svelte file: 

<script>
    import { Geolocation } from '@capacitor/geolocation';

    let loc = null;
    async function getCurrentPosition(){
        const res = await Geolocation.getCurrentPosition()
        loc = res
    }
</script>

<div>
    <h1>Geolocation</h1>
    <p>Your location is:</p>
    <p>Latitude: {loc?.coords.latitude}</p>
    <p>Longitude: {loc?.coords.longitude}</p>

    <button on:click={getCurrentPosition}>
        Get Current Location
    </button>
</div>

<style>
    div {
        padding-top: 50px;
    }
</style>

With the landing page updated, navigate back to http://localhost:5173/ and we should see the generic Geolocation page. If you click on Get Current Location in the browser, you should be prompted to share your location and you’ll get your current coordinates if you agree to share your location: 

If you are just looking to integrate Sveltekit and Capacitor then you are done! However, if you want to take your Sveltekit projects to mobile then continue reading.

Sveltekit On Mobile

In order to get Sveltekit on mobile, we’ll need to make some changes to our project. First thing is to update our capacitor.config.ts file webDir config option to “build”. Why do we do this? When we alter our Sveltekit project, we’ll be turning it into a static application and it will build our application to a folder called build:

import { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  appId: 'com.example.app',
  appName: 'my-app',
  webDir: 'build',
  bundledWebRuntime: false
};

export default config;

Now that we’ve updated our Capacitor settings, let’s change out Sveltekit project to a static application by downloading the proper static adapter package:

npm i -D @sveltejs/adapter-static

After the package is installed, we’ll need to alter svelte.config.js file from the auto-adapter to static:

import adapter from '@sveltejs/adapter-static';
import { vitePreprocess } from '@sveltejs/kit/vite';

/** @type {import('@sveltejs/kit').Config} */
const config = {
	// Consult https://kit.svelte.dev/docs/integrations#preprocessors
	// for more information about preprocessors
	preprocess: vitePreprocess(),

	kit: {
		// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
		// If your environment is not supported or you settled on a specific environment, switch out the adapter.
		// See https://kit.svelte.dev/docs/adapters for more information about adapters.
		adapter: adapter({
			// default options are shown. On some platforms
			// these options are set automatically — see below
			pages: 'build',
			assets: 'build',
			fallback: null,
			precompress: false,
			strict: true
		})
	}
};

export default config;

With the svelte.config.js updated, we’ll need to add a prerender option by creating a +layout.js page to src/routes and just add the following export to +layout.js:

export const prerender = true;

After adding and updating the +layout.js page, we’ll need to add our mobile platforms, re-build our project to create the build folder, and sync our web app to Capacitor to get our mobile dependencies updated:

npm install @capacitor/android
npm install @capacitor/ios
npx cap add android
npx cap add ios
npm run build
npx cap sync

The next part is dependent on if you’ll be running Android, iOS, or both but you’ll need to configure the permissions to allow Geolocation to run on your device. For more information on native device permission, please visit the @capacitor/geolocation documentation. For Android, you’ll update the AndroidManifest.xml file at android/app/src/main/AndroidManifest.xml in your IDE and for iOS you’ll update the info.plist file once you open the project in XCode.

Open your Sveltekit project in iOS/Android:

npx cap open ios
npx cap open android

Run your emulator and your Sveltekit app will be running on mobile!:

Final Thoughts

While setting up Sveltekit with Capacitor may be different than React, Vue, or Angular it is entirely possible to make your Sveltekit project cross-platform. All it takes is a little configuration and a few minutes of your time to make your project work on the web or mobile. If you have any questions about getting your Sveltekit project set up with Capacitor feel free to ask the Ionic team at our official Discord server!


Logan Brade