View Sync
Appilot's view-sync signal lets your application declare which view (page/section) the user is currently on. This gives the AI assistant exact context without relying on URL matching or DOM scraping.
(For the developer package you install, see appilot. This page is only about reporting the current view. To let the agent call your functions, see Client actions.)
Quick Start
Add this to your application:
<script>
window.__appilot = { view: 'dashboard' };
</script>
The view value should match the slug or path of a view configured in your Appilot backoffice.
Reactive Updates (SPAs)
For single-page applications where the user navigates without full page reloads:
Option 1: Update the property directly
// When user navigates to a new page
window.__appilot = { view: 'modules/editor' };
Option 2: Use the CustomEvent API
window.dispatchEvent(new CustomEvent('appilot:viewchange', {
detail: { view: 'modules/editor' }
}));
The extension and widget listen for this event and immediately re-detect the view.
Option 3: Call the widget directly
window.Appilot.setView('modules/editor');
Available once the widget bundle has loaded, so it suits a page that already
waits for the widget. There is no window.__appilot.setView: the property form
is data, and the method lives on window.Appilot.
Which surface reads which
| Entry point | Widget | Extension |
|---|---|---|
window.__appilot = { view } | Yes | Yes |
appilot:viewchange event | Yes | Yes |
window.Appilot.setView(view) | Yes | No, there is no widget to call |
The property and the event are the portable pair: set the property so a surface
arriving late still reads the current view, and dispatch the event so a surface
already running updates at once. window.Appilot.getView() reads back what the
widget currently believes, including which method detected it.
Framework Examples
React
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
function AppilotViewSync() {
const location = useLocation();
useEffect(() => {
const viewMap = {
'/': 'home/dashboard',
'/modules': 'modules/list',
'/settings': 'settings/general',
};
const view = viewMap[location.pathname];
if (view) {
window.dispatchEvent(new CustomEvent('appilot:viewchange', {
detail: { view }
}));
}
}, [location.pathname]);
return null;
}
Vue 3
<script setup>
import { watch } from 'vue';
import { useRoute } from 'vue-router';
const route = useRoute();
watch(() => route.path, (path) => {
const viewMap = { '/': 'home/dashboard', '/modules': 'modules/list' };
const view = viewMap[path];
if (view) {
window.dispatchEvent(new CustomEvent('appilot:viewchange', {
detail: { view }
}));
}
});
</script>
Vanilla JavaScript
// After any navigation or page transition
function notifyAppilot(viewPath) {
window.dispatchEvent(new CustomEvent('appilot:viewchange', {
detail: { view: viewPath }
}));
}
// Example: after loading a new section
notifyAppilot('services/appointments/step-2');
When to Use View Sync
| Scenario | Recommended Strategy |
|---|---|
| Traditional multi-page app | URL Pattern (auto-detected) |
| SPA with meaningful URLs | URL Pattern (auto-detected) |
| SPA where URL doesn't change (Vaadin, GWT) | View sync or DOM Selector |
| App you control the source code of | View sync (most reliable) |
| Third-party app you can't modify | DOM Selector or URL Pattern |
View sync is always the most reliable detection method because it's an explicit declaration from your application, not an inference from the DOM or URL.
Fallback Behavior
If view sync is not integrated, the extension and widget automatically fall back to:
- URL pattern matching
- DOM selector matching
- Page title matching
These are configured per-view in the Appilot backoffice.