Integrating a store locator into your React or Next.js application is straightforward. This guide covers the essentials to get you up and running.
Start with our Quick Start Guide to create your account, add locations, and configure your map. Then come back here to integrate with React.
Before You Start
You'll need:
- A Storepoint account with at least one location added
- A React project (Create React App, Vite, Next.js, etc.)
Basic Integration
The simplest way to add a store locator to a React component:
import { useEffect, useRef } from 'react';
const WIDGET_ID = 'YOUR_WIDGET_ID';
const CONTAINER_ID = 'storepoint-locator';
function StoreLocator() {
const widgetRef = useRef(null);
useEffect(() => {
// Create and load the embed script
const script = document.createElement('script');
script.src = 'https://widget.storepoint.co/embed.js';
script.async = true;
script.onload = () => {
// Initialize the widget after script loads
if (window.StorepointWidget && !widgetRef.current) {
const widget = new window.StorepointWidget(
WIDGET_ID,
`#${CONTAINER_ID}`,
{}
);
widget.load();
widgetRef.current = widget;
}
};
document.head.appendChild(script);
// Cleanup on unmount
return () => {
if (script.parentNode) {
script.parentNode.removeChild(script);
}
};
}, []);
return <div id={CONTAINER_ID} style={{ width: '100%', minHeight: '500px' }} />;
}
export default StoreLocator;
Replace 'YOUR_WIDGET_ID' with your widget ID from the Storepoint dashboard.
Your widget ID is the unique identifier in your embed code. It looks like a short alphanumeric string (e.g., abc123). Find it in your Embed settings.
Next.js Integration
For Next.js projects, the widget must load client-side only. Use dynamic imports to prevent SSR issues:
// components/StoreLocator.tsx
'use client';
import { useEffect, useRef, useState } from 'react';
interface StoreLocatorProps {
widgetId: string;
}
export default function StoreLocator({ widgetId }: StoreLocatorProps) {
const widgetRef = useRef(null);
const [isClient, setIsClient] = useState(false);
// Generate a stable container ID based on the widget ID
const containerId = `storepoint-${widgetId}`;
useEffect(() => {
setIsClient(true);
}, []);
useEffect(() => {
if (!isClient) return;
let script = document.querySelector('script[src*="widget.storepoint.co/embed.js"]');
const initializeWidget = () => {
if (window.StorepointWidget && !widgetRef.current) {
const widget = new window.StorepointWidget(
widgetId,
`#${containerId}`,
{}
);
widget.load();
widgetRef.current = widget;
}
};
if (script) {
initializeWidget();
} else {
script = document.createElement('script');
script.src = 'https://widget.storepoint.co/embed.js';
script.async = true;
script.onload = initializeWidget;
document.head.appendChild(script);
}
}, [isClient, widgetId, containerId]);
if (!isClient) {
return <div style={{ minHeight: '500px' }}>Loading store locator...</div>;
}
return <div id={containerId} style={{ width: '100%', minHeight: '500px' }} />;
}
Then use dynamic import in your page:
// app/store-locator/page.tsx
import dynamic from 'next/dynamic';
const StoreLocator = dynamic(() => import('../components/StoreLocator'), {
ssr: false,
loading: () => <div style={{ minHeight: '500px' }}>Loading...</div>
});
export default function StoreLocatorPage() {
return (
<main>
<h1>Find a Location</h1>
<StoreLocator widgetId="YOUR_WIDGET_ID" />
</main>
);
}
The Storepoint widget requires browser APIs and cannot render server-side. Always use the 'use client' directive (App Router) or dynamic imports with ssr: false (Pages Router).
Listening for Events
You can listen for widget events to integrate with your app's state or analytics:
useEffect(() => {
// After widget loads...
widget.on('search', (data) => {
console.log('User searched:', data.query);
});
widget.on('location-result-item-click', (data) => {
console.log('Location clicked:', data.name);
});
}, []);
See the JavaScript API documentation for all available events and methods.
Having Trouble?
If you run into any issues, contact us and we'll help get it sorted. Please include details about your React setup and any error messages you're seeing.
Next Steps
- Set up filters and tags to help customers find specific location types
- Explore embed code options for pre-filtered locators
- JavaScript API documentation for advanced integrations