Keep your usersin the loop
Your marketing team ships in-app messages from a dashboard. Your devs drop in two lines of code. Everyone sees the analytics.
14-day free trial. Two lines of code. Live in 5 minutes.
New dashboard, less clicks
Analytics page now loads 3× faster.
Everything you need to engage your users
A focused toolkit for in-app messaging — from creation to analytics.
In-app messages
Title, description, CTA, intent. Multiple statuses. Per-locale translations. Everything you'd expect.
Slots & modes
Developers define display locations (slots) once. Marketing fills them with messages and publishes — no code changes needed.
A/B testing
Put multiple messages in the same slot and switch the mode to A/B test. Each user gets a consistent variant, automatically.
Multi-locale
Translate every field per locale. Field-by-field fallback to the default — no half-translated messages slipping through.
Real-time analytics
Impressions, clicks, dismissals, CTR. Per message, per slot, project-wide. Auto-tracked by the SDK.
Lightweight SDK
A React hook fetches your messages once. Tiny bundle, zero runtime dependencies, works with any setup.
One SDK, every kind of message
You decide how to render. The intent field hints at the right visual style — info, success, warning. Same hook, three appearances.
Trial ending in 3 days
Pick a plan to keep your team's access.
Payment received
Your subscription is active.
The simple idea
Marketing ships messages.
Devs ship features.
No more "can you push a quick banner change?" Slack messages. No more deploys for copy tweaks. Each team owns its lane.
How it works
Three steps from zero to first message live in your app.
Devs add the SDK
Wrap your app in the provider and drop a `useSlot()` hook where you want messages to appear. Two lines.
Marketing writes & publishes
Pick a slot, write the message, hit publish. Add more messages for A/B testing or rotation.
Engagement, measured
Impressions, clicks, dismissals stream back. See what works, iterate without a deploy.
Two lines of code, every framework
Wrap your app with the provider. Call the hook wherever you need messages. That's the integration.
import { LoopanaProvider, useSlot } from '@loopana/react'
function App() {
return (
<LoopanaProvider apiKey="pk_live_xxx">
<YourApp />
</LoopanaProvider>
)
}
function ChatPage() {
const { message } = useSlot("chat-banner")
if (!message) return null
return (
<div>
<h3>{message.title}</h3>
{message.description && <p>{message.description}</p>}
</div>
)
}