@despia/local
v1.0.8
Published
Universal build plugin to generate despia/local.json manifest for offline caching in Despia web-native apps. Supports Vite, Webpack, Rollup, Nuxt, SvelteKit, Astro, Remix, esbuild, Parcel, and more.
Maintainers
Readme
@despia/local
Universal build plugin to generate despia/local.json manifest for Despia web-native apps. This manifest enables Despia's local server, which runs your web app from a local HTTP server on-device, providing full offline functionality with seamless updates.
Note: Despia's local server is optional. Normally, the Despia runtime can run your web app directly from a URL. Despia's local server is for developers who need extra performance and full true native offline support.
Store Compliant: Despia's local server is fully compliant with Apple App Store and Google Play Store guidelines. It downloads and caches web content (HTML, CSS, JavaScript) for offline display in a WebView - identical to how web browsers work. No native code or executables are downloaded. See Store Compliance & Security section for detailed compliance information.
Features
- Universal Support - Works with Vite, Webpack, Rollup, Nuxt, SvelteKit, Astro, Remix, esbuild, Parcel, and more
- Zero Dependencies - Uses only Node.js built-in modules
- Automatic Asset Discovery - Collects all output files (JS, CSS, images, fonts, HTML, etc.)
- Root-Relative Paths - Formats all paths as root-relative (starting with
/) - Sorted Output - Alphabetically sorted paths for consistent builds
- Standalone Script - Can be used with any build system via CLI
About Despia's Local Server
Note: Despia's local server is optional. Normally, the Despia runtime can run your web app directly from a URL. Despia's local server is for developers who need extra performance and full true native offline support.
Despia's local server enables your web app to run entirely from a local HTTP server on-device, providing a native app experience with full offline functionality.
Architecture
The Despia native container consists of:
Native iOS/Android Container: The native binary submitted to App Store/Play Store
- WebView for UI rendering (WKWebView on iOS, WebView on Android)
- JavaScript bridge for native API access (exposes native capabilities to web content via
despia-native) - Local HTTP server infrastructure (runs on-device only)
- Storage and update management systems
Web Content Layer (downloaded and cached):
- HTML, CSS, JavaScript files
- Images, fonts, and other static assets
- Served from
http://localhostafter initial hydration
Key Architecture Principles:
- Web content updates (HTML/CSS/JS only)
- JavaScript bridge provides access to native APIs already in the binary
- No native code execution or downloads
- No executable binaries downloaded
- All native code fixed at App Store/Play Store submission
How It Works
Initial Installation The App Store/Play Store binary contains the native iOS/Android container (see Architecture above):
- Native code (Swift/Kotlin) for platform integration
- WebView component for UI rendering
- JavaScript bridge for native API access (exposes native capabilities to web content via
despia-native) - Local HTTP server infrastructure (runs on-device only)
- Storage and update management systems
- No web app assets (HTML, CSS, JavaScript) are bundled in the binary
This approach keeps initial install sizes minimal and allows for rapid iteration of web UI without requiring app store resubmissions. Important: All native code, the JavaScript bridge, and app functionality are fixed at submission time and cannot be changed. Only web content (HTML/CSS/JS) can be updated.
First Launch Hydration
On first app launch, Despia securely downloads your latest web build (HTML, CSS, JavaScript, images, fonts) from your repository and stores it locally on the device. The local HTTP server then begins serving your web content from http://localhost, providing a stable origin for your web application.
Note on Compliance: This process downloads and caches web content files only. No native code, executables, or binary files are downloaded. The JavaScript executes within the WebView's sandbox, identical to how Safari or Chrome render web pages.
Offline Operation After the initial hydration, your app operates completely offline:
- Instant app boot times (no network requests)
- No network connectivity required
- Full SPA routing and navigation
- Deep linking support
- Stable HTTP origin (
http://localhost) for hybrid app flexibility
If the device goes offline permanently, the app continues to function using the last hydrated version, ensuring reliability even without connectivity.
Seamless Updates When connectivity is available, Despia checks for updates in the background and downloads new web builds atomically. Updates are applied on the next app launch, ensuring:
- No partial or broken states
- Atomic updates for reliability
- No app store resubmission required for web UI changes
- Background updates that don't interrupt user experience
Important: Updates only change web content (HTML, CSS, JavaScript). Native code, permissions, and app functionality remain unchanged from the original App Store/Play Store submission.
Store Compliance & Security
Compliance Summary for App Reviewers:
Despia's local server downloads and caches web content files (HTML, CSS, JavaScript, images) for offline display in a WebView. This is identical to how web browsers (Safari, Chrome) download and render web pages.
Key Compliance Points:
- No native code is downloaded or executed
- No executable binaries (
.so,.dylib,.dex) are downloaded - All native code and native API capabilities are fixed at App Store/Play Store submission
- JavaScript executes only within WebView sandbox (same as browsers)
- All content served from on-device
localhostserver - App permissions and which native APIs are available cannot be changed
- Web UI can be updated to use existing native APIs (already in binary) in new ways
This approach is explicitly permitted under both App Store and Play Store policies, as it involves web content rendering, not native code execution.
Compliance Validation Tools
For conditionally rendering UI elements based on the Despia Native SDK runtime version, consider using despia-version-guard, a recommended tool in the Despia ecosystem. This framework-agnostic solution helps ensure store compliance and reliability by:
- Conditionally rendering UI based on
window.bundleNumber(Despia Native SDK runtime version) - Version-gating major UI shifts to maintain store compliance
- Preventing broken UI when Despia adds new runtime features that older users don't have
- Supporting React, Vue, Angular, Svelte, and Vanilla JS/Web Components
despia-version-guard complements @despia/local by enabling you to build conditional UI for major version shifts while remaining store-compliant. This is particularly useful for:
- Major UI Shifts: Show new UI only to users with the required minimum version
- Deprecation: Hide legacy features when version exceeds maximum
- Upgrade Prompts: Conditionally show upgrade buttons based on version
- Store Compliance: Ensure app review compatibility by version-gating major changes
- Enterprise Reliability: Prevent broken UI when Despia adds new runtime features
Installation:
npm install despia-version-guardExample Usage (React):
import { VersionGuard } from 'despia-version-guard';
// Only show this feature if version is 21.0.3 or higher
<VersionGuard min_version="21.0.3">
<NewFeatureComponent />
</VersionGuard>See the despia-version-guard documentation for framework-specific usage and API details.
Despia's local server is fully compliant with both Apple App Store and Google Play Store guidelines. This section explains the compliance in detail.
Apple App Store Compliance
Guideline 3.3.2 - Code Execution:
"Apps must not download, install, or execute code which introduces or changes features or functionality of the app, including other apps."
Compliance Statement: Despia's local server complies with this guideline because:
No Native Code Execution: The app does not download, install, or execute any native code (Swift, Objective-C, C++, etc.). All native code is fixed at App Store submission time and cannot be modified.
Web Content Rendering Only: Only web content assets (HTML, CSS, JavaScript) are downloaded and rendered. This is identical to how Safari, Chrome, and other web browsers load and display web content. The JavaScript executes within the WebView's sandbox, not as native code.
Fixed Native Functionality: All native capabilities, permissions, and native API implementations are determined at submission time. The downloaded web content cannot change:
- App permissions (declared in Info.plist)
- Which native APIs are available in the binary
- Native API implementations
- App Store metadata
- Binary behavior
- System integration
However, the web UI can be updated to use existing native APIs in new ways. For example, if Face ID is already implemented in the native code and exposed through the WebView bridge, the web UI can be updated to call Face ID from new parts of the app. This is compliant because the native capability already exists in the submitted binary - only the web UI's usage of it changes.
Note: This follows the same pattern as Expo, which has been generally accepted by app stores. However, Apple's interpretation of "feature changes" under Guideline 3.3.2 is subjective, and your app could still face review challenges. It's recommended to be conservative with updates that significantly change app behavior, even when using existing native APIs.
On-Device Execution: All web content is served from a local HTTP server running on-device (
localhost). No remote code execution occurs.
This approach is explicitly permitted under App Store guidelines, as evidenced by:
- Safari and other browsers downloading and rendering web content
- Apps using WKWebView to display web content
- Enterprise apps using web-based UIs
- Apps that cache web content for offline use
Google Play Store Compliance
Play Store Policy - Malicious Behavior:
"Apps must not download executable code (e.g., dex, JAR, .so files) from a source other than Google Play."
Compliance Statement: Despia's local server complies with this policy because:
No Executable Code Downloads: The app does not download any executable code (
.dex,.jar,.so,.apk, or native binaries). Only web content files (HTML, CSS, JavaScript, images, fonts) are downloaded.Web Content Rendering: JavaScript files are executed within the WebView's JavaScript engine, not as native executables. This is the same mechanism used by Chrome and other Android browsers.
Fixed Native Binary: The APK/AAB submitted to Google Play contains all native code. No native code is downloaded or executed after installation.
Sandboxed Execution: All web content executes within the WebView's security sandbox, with permissions and capabilities fixed at APK submission time.
However, the web UI can be updated to use existing native APIs in new ways. For example, if biometric authentication is already implemented in the native code and exposed through the WebView bridge, the web UI can be updated to call it from new parts of the app. This is compliant because the native capability already exists in the submitted APK - only the web UI's usage of it changes.
This approach is explicitly permitted under Play Store policies, as evidenced by:
- Chrome and other browsers rendering web content
- Apps using WebView to display web content
- Progressive Web Apps (PWAs) that cache content
- Apps that update UI via web technologies
Technical Implementation Details
What Gets Downloaded:
- HTML files (markup)
- CSS files (styling)
- JavaScript files (executed in WebView sandbox)
- Images, fonts, and other static assets
- Native code (Swift, Kotlin, C++, etc.) - NOT downloaded
- Executable binaries (
.so,.dylib,.dex, etc.) - NOT downloaded - Native libraries or frameworks - NOT downloaded
What Cannot Change:
- Native app permissions (declared in Info.plist/AndroidManifest.xml)
- App Store/Play Store metadata
- Native API implementations and capabilities
- System integration capabilities
- App signing and security model
- Which native APIs are available in the binary
What CAN Change (Compliant Updates):
- Usage of Existing Native APIs: The web UI can be updated to use native APIs that are already built into the binary and exposed through the WebView bridge. For example:
- If Face ID/Touch ID is already implemented in the native code, the web UI can be updated to call it from new parts of the app
- If camera access is already granted, the web UI can be updated to use it in new features
- If location services are already available, the web UI can be updated to request location in new screens
- Any native capability that exists in the submitted binary can be exposed to new parts of the web UI via updates
Important Distinction:
- Compliant: Updating web content to use existing native APIs (e.g., adding Face ID to a new login screen when Face ID is already in the binary)
- Not Compliant: Downloading new native code or adding new native capabilities that weren't in the original submission
This is compliant because:
- The native API/capability already exists in the binary submitted to the stores
- The WebView bridge was already configured to expose these APIs at submission time
- Only the web UI is changing to call existing native functions
- No new native code, permissions, or capabilities are being added
This follows the same pattern as established frameworks like Expo, which uses JavaScript bridges to expose native APIs to web content and has been generally accepted by app stores.
Important Disclaimer: While this approach is technically compliant and follows established patterns, Apple's interpretation of Guideline 3.3.2 regarding "feature changes" is subjective. Apps using this pattern have been generally accepted, but your app could still face review challenges, especially if updates significantly change app behavior or functionality. It's recommended to:
- Be conservative with updates that dramatically change user-facing features
- Test thoroughly before submitting significant UI/UX changes
- Be prepared to explain how updates use existing native APIs if questioned during review
- Consider submitting major feature additions through the normal App Store review process when possible
Security Model:
- All web content is served from
http://localhost(on-device only) - WebView sandbox enforces same-origin policy
- No network access to external servers after initial hydration
- Content Security Policy (CSP) can be enforced
- All execution happens within WebView's security boundaries
HTTP vs HTTPS for Local Apps
Despia's local server uses HTTP for serving local content. This design choice provides important flexibility for hybrid apps while maintaining full security through localhost's inherent security guarantees.
Security Guarantees of localhost
http://localhost is a secure context in all modern browsers and provides inherent security guarantees:
Reserved Hostname:
localhostis a reserved hostname that maps exclusively to127.0.0.1(IPv4) or::1(IPv6) on the local machine. It cannot be redirected or spoofed by external attackers.No Network Exposure: Traffic to
localhostnever leaves the device. All communication stays within the local machine, eliminating network-based attack vectors.Secure Context:
http://localhostIS a secure context in browsers, meaning all modern Web APIs work perfectly:- Service Workers
- Web Crypto API
- Geolocation API
- MediaDevices API
- And all other secure-context APIs
Cannot Be Spoofed: External attackers cannot redirect
localhostto their servers. The hostname is hardcoded to point to the local machine, providing the same security guarantees as HTTPS for local-only content.On-Device Execution: Combined with WebView sandbox isolation, same-origin policy, and Content Security Policy,
localhostprovides a secure execution environment without requiring encryption overhead.
Why HTTP is the Right Choice for Hybrid Apps
Protocol Flexibility: HTTP allows your app to load resources from both HTTPS (external APIs, CDNs) and HTTP (local server) origins without mixed content warnings. This is crucial for hybrid apps that need to:
- Load local assets from
http://localhost - Make API calls to
https://api.example.com - Embed external HTTPS resources (images, fonts, etc.)
- Work seamlessly across different network configurations
- Load local assets from
Secure Context Support:
http://localhostis treated as a secure context by browsers, meaning all modern Web APIs (Service Workers, Web Crypto API, Geolocation, etc.) work without requiring HTTPS.Inherent Security:
localhostis a reserved hostname that can only point to the local machine (127.0.0.1). This means:- Traffic never leaves the device (no network exposure)
- Cannot be spoofed or redirected by external attackers
- Provides the same security guarantees as HTTPS for local-only content
Simplified Development: HTTP eliminates certificate management complexity for local development and testing. No need to generate, install, or manage SSL certificates for localhost.
Cross-Origin Resource Sharing (CORS): HTTP on localhost provides more predictable CORS behavior when mixing local and remote resources, reducing integration complexity.
Performance: HTTP has slightly lower overhead than HTTPS, which is beneficial for local file serving where encryption isn't necessary since all content is already on-device and
localhostprovides inherent security.Compatibility: HTTP works consistently across all platforms and WebView implementations without requiring certificate pinning or trust store configuration.
When HTTPS Might Be Needed
While HTTP with localhost provides full security for local-only content, HTTPS might be required in specific scenarios:
Enterprise Compliance: Some enterprise security policies require all network traffic (including local) to be encrypted, making HTTPS a requirement for certain deployment scenarios.
Certificate Validation: HTTPS with proper certificate validation provides additional assurance that the local server hasn't been tampered with or replaced by malicious software. This can be important in high-security environments.
Security-in-Depth: HTTPS enforces encryption even for local traffic, following security-in-depth principles. This protects against potential local network attacks or device-level interception in shared or untrusted environments.
Content Security Policy (CSP): HTTPS makes it easier to enforce strict CSP headers without mixed content warnings, though this is less relevant for local-only content.
Browser Security Indicators: HTTPS provides visual security indicators (lock icon) that can increase user trust, even for local content.
Note: For most hybrid app scenarios, HTTP with localhost provides the right balance of flexibility and security. The security comes from the reserved hostname and on-device execution, not encryption. However, if your use case requires HTTPS (e.g., enterprise compliance, strict security policies), you can configure your WebView to use HTTPS for the local server.
Current Implementation Rationale
Despia's local server uses HTTP because the primary use case is hybrid apps that need maximum flexibility to mix local and remote resources. The security model relies on:
- Secure Context:
http://localhostIS a secure context, enabling all modern Web APIs - Reserved Hostname:
localhostis a reserved hostname (127.0.0.1) that cannot be spoofed - On-Device Execution: All traffic stays on-device (no network exposure)
- WebView Sandbox Isolation: WebView enforces security boundaries
- Same-Origin Policy: Browser enforces same-origin policy
- Content Security Policy: CSP can be enforced when configured
Security comes from the reserved hostname and on-device execution, not encryption. For most hybrid app scenarios, HTTP provides the right balance of flexibility and security.
Comparison to Similar Technologies
This approach is conceptually and technically identical to:
- Web Browsers (Safari, Chrome): Download and render web content from servers
- Expo: Uses JavaScript bridge to expose native APIs to React Native web content
- Electron Apps: Update web UI content without changing native code
- Progressive Web Apps: Cache web content for offline use
- Enterprise MDM Solutions: Deploy web-based UIs to managed devices
- Hybrid Mobile Apps: Use WebView to display web content
The key distinction that ensures compliance: Web content rendering is not code execution in the App Store/Play Store policy sense. Native code execution is what the policies restrict, and Despia does not perform any native code execution.
Note: Expo follows the same pattern of exposing native APIs through JavaScript bridges and has been generally accepted by app stores. However, as with any approach involving web content updates, there's always a possibility of review challenges depending on how Apple interprets "feature changes" in specific cases.
Practical Example: Using Existing Native APIs
To illustrate compliance with using existing native APIs:
Scenario: An app is submitted with Face ID/Touch ID already implemented in the native code and exposed through the WebView bridge. The initial web UI only uses Face ID on the login screen.
Compliant Update: The web UI can be updated via OTA to also use Face ID on:
- A new settings screen
- A payment confirmation screen
- Any other new feature
Why This Is Compliant:
- Face ID native code was already in the binary at App Store submission
- The WebView bridge was already configured to expose Face ID to JavaScript
- Only the web UI JavaScript is changing to call the existing native function
- No new native code, permissions, or capabilities are being added
Not Compliant: Downloading new native code to add Face ID support that wasn't in the original submission.
This is analogous to:
- A web browser using JavaScript to call
navigator.geolocationin different parts of a website - Expo apps updating React Native code to use existing native modules in new screens
- An Electron app updating its web UI to use existing Electron APIs in new features
- A hybrid app using existing Cordova plugins in new screens
Review Considerations: While this pattern is technically compliant and follows established frameworks like Expo, Apple's interpretation of Guideline 3.3.2 can be subjective. If your update significantly changes app behavior or introduces major new user-facing features, consider whether it might be better to submit through the normal App Store review process to avoid potential challenges.
Developer Responsibility
When submitting apps using Despia's local server:
App Store Submission: Clearly state that the app uses a WebView to display web content that may be cached for offline use. This is standard practice and does not require special disclosure.
Play Store Submission: No special disclosure required. The app uses standard Android WebView components to display web content.
Privacy Policy: If your app collects data through the web content, ensure your privacy policy covers this, as required by both stores.
Content Guidelines: Ensure all web content complies with App Store and Play Store content policies, as the web content is part of your app submission.
Update Strategy: Be mindful that while using existing native APIs in new ways is technically compliant (following the same pattern as Expo), Apple's interpretation of "feature changes" under Guideline 3.3.2 is subjective. Consider:
- Being conservative with updates that dramatically change app behavior
- Testing thoroughly before deploying significant UI/UX changes
- Being prepared to explain how updates use existing native APIs if questioned
- Submitting major feature additions through normal App Store review when appropriate
Version-Based UI Rendering: Consider using
despia-version-guardto conditionally render UI elements based on the Despia Native SDK runtime version. This helps maintain store compliance by version-gating major changes and prevents broken UI for users with older runtime versions.
The local.json Manifest
The despia/local.json manifest generated by this plugin serves as an asset inventory for Despia's local server. It contains a complete list of all assets that need to be cached locally, enabling:
- Complete Asset Discovery: Ensures all files (JS, CSS, images, fonts, HTML) are properly cached
- Efficient Updates: Allows Despia to determine which assets have changed between builds
- Reliable Offline Operation: Guarantees all required assets are available offline
- Atomic Updates: Enables safe, complete updates without partial states
This manifest is automatically used by Despia during the hydration and update processes to ensure your app has everything it needs to run offline.
Installation
npm install --save-dev @despia/localQuick Start
Option 1: Framework-Specific Plugin (Recommended)
Choose the plugin for your framework below.
Option 2: Standalone Script (Universal)
Add to your package.json:
{
"scripts": {
"build": "your-build-command",
"postbuild": "despia-local"
}
}Or run manually:
npx despia-local [outputDir] [entryHtml] [--output|-o manifestPath]Options:
--output,-o <path>- Custom output path for manifest file (useful for hosting providers)--help,-h- Show help message
Examples:
# Default: generates manifest in outputDir/despia/local.json
npx despia-local dist
# Custom output location (e.g., for Vercel/Netlify)
npx despia-local dist --output public/despia/local.json
npx despia-local build -o public/manifest.jsonFramework Support
Vite
// vite.config.js
import { defineConfig } from 'vite';
import { despiaLocalPlugin } from '@despia/local/vite';
export default defineConfig({
plugins: [
// ... your other plugins
despiaLocalPlugin({
outDir: 'dist', // optional, default: 'dist'
entryHtml: 'index.html' // optional, default: 'index.html'
})
]
});Works with:
- Vite + React
- Vite + Vue
- Vite + Svelte
- Vite + Preact
- Vite + Lit
- Any Vite-based project
Webpack
// webpack.config.js
const DespiaLocalPlugin = require('@despia/local/webpack');
module.exports = {
// ... your config
plugins: [
// ... your other plugins
new DespiaLocalPlugin({
outDir: 'dist', // optional, default: 'dist'
entryHtml: 'index.html' // optional, default: 'index.html'
})
]
};Works with:
- Create React App (eject or CRACO)
- Vue CLI
- Angular (custom webpack config)
- Any webpack-based project
Rollup
// rollup.config.js
import { despiaLocal } from '@despia/local/rollup';
export default {
// ... your config
plugins: [
// ... your other plugins
despiaLocal({
outDir: 'dist',
entryHtml: 'index.html'
})
]
};Nuxt
// nuxt.config.js
export default {
modules: ['@despia/local/nuxt'],
despiaLocal: {
entryHtml: 'index.html'
}
}Or as a local module:
// modules/despia-local.js
import DespiaLocalModule from '@despia/local/nuxt';
export default DespiaLocalModule;SvelteKit
// vite.config.js
import { sveltekit } from '@sveltejs/kit/vite';
import { despiaLocalSvelteKit } from '@despia/local/sveltekit';
export default {
plugins: [
sveltekit(),
despiaLocalSvelteKit({
entryHtml: 'index.html'
})
]
};Astro
// astro.config.mjs
import { defineConfig } from 'astro/config';
import despiaLocal from '@despia/local/astro';
export default defineConfig({
integrations: [
despiaLocal({
entryHtml: 'index.html',
outDir: 'dist'
})
]
});Remix
// vite.config.js (Remix uses Vite)
import { remix } from '@remix-run/dev';
import { despiaLocalRemix } from '@despia/local/remix';
export default {
plugins: [
remix(),
despiaLocalRemix({
entryHtml: 'index.html',
outDir: 'build/client'
})
]
};esbuild
import { build } from 'esbuild';
import { despiaLocalEsbuild } from '@despia/local/esbuild';
await build({
entryPoints: ['src/index.js'],
outdir: 'dist',
plugins: [
despiaLocalEsbuild({
outDir: 'dist',
entryHtml: 'index.html'
})
]
});Parcel
// .parcelrc
{
"extends": "@parcel/config-default",
"plugins": {
"@despia/local/parcel": true
}
}Or in package.json:
{
"parcel": {
"plugins": {
"@despia/local/parcel": true
}
}
}Other Build Tools
For any build tool not listed above, use the standalone CLI script:
{
"scripts": {
"build": "your-build-command",
"postbuild": "despia-local dist index.html"
}
}Configuration Options
All plugins accept the following options:
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| outDir | string | 'dist' | Output directory to scan for assets |
| entryHtml | string | 'index.html' | Entry HTML filename to include in manifest |
Output Format
The generated despia/local.json file contains an object with the entry HTML path and a sorted array of asset paths:
{
"entry": "/index.html",
"assets": [
"/index.html",
"/assets/app.abc123.css",
"/assets/app.def456.js",
"/assets/logo.xyz789.png"
]
}entry: The entry HTML file path (e.g.,/index.html). Required - Local apps always need an entry point for client-side rendering. The entry path is also included in theassetsarray (unlessskipEntryHtmlis enabled).assets: A sorted array of all asset paths, including the entry file. WhenskipEntryHtmlis enabled, the entry is still required in the manifest but won't be included in theassetsarray.
Examples
React + Vite
// vite.config.js
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { despiaLocalPlugin } from '@despia/local/vite';
export default defineConfig({
plugins: [
react(),
despiaLocalPlugin()
]
});Vue + Vite
// vite.config.js
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { despiaLocalPlugin } from '@despia/local/vite';
export default defineConfig({
plugins: [
vue(),
despiaLocalPlugin()
]
});Angular
// angular.json - Add to build configuration
{
"projects": {
"your-app": {
"architect": {
"build": {
"builder": "@angular-builders/custom-webpack:browser",
"options": {
"customWebpackConfig": {
"path": "./webpack.config.js"
}
}
}
}
}
}
}// webpack.config.js
const DespiaLocalPlugin = require('@despia/local/webpack');
module.exports = {
plugins: [
new DespiaLocalPlugin({ outDir: 'dist' })
]
};Svelte + Vite
// vite.config.js
import { defineConfig } from 'vite';
import { svelte } from '@sveltejs/vite-plugin-svelte';
import { despiaLocalPlugin } from '@despia/local/vite';
export default defineConfig({
plugins: [
svelte(),
despiaLocalPlugin()
]
});How the Plugin Works
- Hook into Build Process - The plugin hooks into your build tool's completion event
- Scan Output Directory - Recursively scans the build output directory for all files
- Collect Asset Paths - Collects paths from both the build tool's bundle metadata and file system
- Normalize Paths - Converts all paths to root-relative format (starting with
/) - Include Entry in Assets - Identifies the entry HTML file and includes it in the assets array (unless
skipEntryHtmlis enabled) - Sort & Write - Sorts asset paths alphabetically and writes object format
{ entry, assets }todespia/local.json
The generated manifest is then used by Despia during app hydration and updates to ensure all assets are properly cached for offline operation.
Notes
- The plugin automatically creates the
despiasubdirectory if it doesn't exist - All paths are normalized to use forward slashes (
/) regardless of OS - Paths are sorted alphabetically for consistent output across builds
- The entry HTML file is always included, even if not found in the output directory
- The
despiadirectory itself is excluded from the manifest to avoid recursion
Troubleshooting
Manifest not generated
- Ensure the build completes successfully
- Check that the output directory exists
- Verify the
outDiroption matches your build configuration - Check console for error messages
Missing assets in manifest
- The plugin scans the entire output directory
- Ensure assets are copied to the output directory during build
- Check that file paths are correctly formatted
Path format issues
- All paths are automatically normalized to root-relative format
- Paths starting with
/are preserved as-is - Windows backslashes are converted to forward slashes
Contributing
Contributions welcome! Please open an issue or submit a pull request.
License
MIT
Related
- Despia - Web-native app platform
- despia-native - JavaScript SDK for accessing native device features (haptics, biometrics, camera, location, push notifications, in-app purchases, and 25+ more APIs)
- despia-version-guard - Framework-agnostic solution for conditionally rendering UI based on Despia Native SDK runtime version
