Apps integration
Behold the artistry of integrating apps within your theme's grand tapestry. Just as a masterful painter weaves vibrant hues into their canvas, you shall weave the functionality of apps into your digital realm.
App Placements
Each theme boasts its unique app placements, with some placements mandated by required apps, like the Express Checkout App. Behold these examples:
| App Placements | Text | Type |
|---|---|---|
| REPLACE_BUYNOW | To show an app instead of the “Buy Now” button | Required |
| BEFORE_HEADER | Show apps on the of of the page | Optional |
| AFTER_HEADER | Show apps after the header section | Optional |
| BEFORE_FOOTER | Show apps before the footer | Optional |
| AFTER_FOOTER | Show apps on the bottom of the page | Optional |
| BEFORE_ADD_TO_CART | Before “Add to cart” button | Optional |
| AFTER_ADD_TO_CART | After “Add to cart” button | Optional |
| AFTER_DESCRIPTION | After description content | Optional |
| REPLACE_REVIEWS | Replace default theme reviews with reviews app | Optional |
App Installation
For testing and experimentation, visit https://markets.storeino.world/apps and install free apps into your store.
Implementation Unveiled
Prepare your symphony of apps by crafting a universal component named "AppLoader.vue" within the components folder.
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { useMainStore } from '@/stores/main';
// Define props
const props = defineProps({
placement: {
type: String,
required: true,
},
});
// Store and Reactive State
const store = useMainStore();
const loading = ref(false);
const { $tools }: any = useNuxtApp();
// Load App Function
function loadApp(app: any, element: HTMLElement | null) {
if (!element) return;
const uid = ${app.route}_${props.placement};
if (!app[loaded_${uid}]) {
try {
const stateApp = store.apps.find((a: any) => a.route === app.route);
if (!stateApp) return;
let { manifest, html, css, js } = $tools.copy(stateApp.loaded);
js = js.replace(
'_DATA_',
JSON.stringify({
placement: props.placement,
...app.config,
}).replace(/"/g, '"')
);
html = html.replace(
new RegExp(app_${app.route}, 'g'),
app_${app.route}_${uid}
);
css = css.replace(
new RegExp(#app_${app.route}, 'g'),
#app_${app.route}_${uid}
);
js = js.replace(
new RegExp(app_${app.route}, 'g'),
app_${app.route}_${uid}
);
app[loaded_${uid}] = { manifest, html, css, js };
} catch (err) {
console.error('Error loading app:', err);
}
}
if (app[loaded_${uid}]) {
const htmlElement = document.createElement('div');
const styleElement = document.createElement('style');
element.append(htmlElement);
htmlElement.innerHTML = app[loaded_${uid}].html;
element.append(styleElement);
styleElement.innerHTML = app[loaded_${uid}].css;
window.eval(app[loaded_${uid}].js);
}
}
// Mounted Lifecycle Hook
onMounted(() => {
const element: any = document.querySelector(#${props.placement});
if (store.apps) {
const apps = store.apps.filter((app: any) =>
app.placement.split('|').includes(props.placement)
);
if (apps.length > 0) {
loading.value = true;
apps.forEach((app: any) => loadApp(app, element));
loading.value = false;
}
}
});
</script>
<template>
<div :id="placement"></div>
</template>With this masterpiece ready, call your symphonic component <app-loader> and serenade it with the enchanting notes of the "placement" parameter.
<template>
<div>
<app-loader placement="BEFORE_HEADER"></app-loader>
<header>
<hav>
<ul>
<li>Home</li>
...
</ul>
</hav>
</header>
</div>
</template>Just as a maestro wields their baton, you now wield the power to orchestrate the harmonious fusion of apps into your theme. Let your digital realm resound with the symphony of innovation and functionality.