Create a professional Store Locator app for Shopify App Store with 3-level dynamic page creation:
=== CORE FUNCTIONALITY ===
APP PURPOSE:
- Merchants upload location data via CSV or API
- App dynamically creates Shopify pages for each location
- Creates main directory page + 3 pages per location
- All pages created using Shopify Admin API (pageCreate/pageUpdate mutations)
- Pages are official Shopify pages with proper URLs
=== LEVEL 1: MAIN DIRECTORY PAGE ===
URL: /pages/store-locations
Created by: Shopify pageCreate mutation
Handle: “store-locations”
FEATURES:
- Centered header: “Our Store Locations” (42px, bold, #202223)
- Subtitle: “Find a store near you” (18px, #6d7175)
- Search box (max-width 500px, centered, blue focus border #5c6ac4)
- Responsive grid of location cards:
- Desktop (>992px): 3 columns
- Tablet (768-992px): 2 columns
- Mobile (<768px): 1 column
- Gap: 24px
CARD DESIGN:
- White background (#ffffff)
- Border: 2px solid #e1e3e5
- Border-radius: 12px
- Padding: 28px
- Box-shadow: 0 2px 4px rgba(0,0,0,0.05)
- Hover effects:
- Transform: translateY(-4px)
- Box-shadow: 0 8px 20px rgba(0,0,0,0.12)
- Border-color: #5c6ac4
- Transition: all 0.3s ease
CARD CONTENT:
- Location name (22px, bold, #202223)
City, Province (15px, #6d7175)- “View Details →” (15px, #5c6ac4, bold)
- Links to: /pages/locations-{slug}
SEARCH FUNCTIONALITY:
- JavaScript filter by name/city/province
- Real-time filtering
- Case-insensitive
=== LEVEL 2: OVERVIEW PAGE ===
URL: /pages/locations-{slug}
Created by: Shopify pageCreate mutation
Handle: locations-{slug}
Title: {Location Name}
LAYOUT:
- Max-width: 900px, centered
- Padding: 40px 20px
- Font: -apple-system, BlinkMacSystemFont, ‘Segoe UI’, Roboto, sans-serif
HEADER SECTION:
- Back button to /pages/store-locations
- Background: #5c6ac4
- Color: white
- Padding: 12px 20px
- Border-radius: 8px
- Hover: background #4959bd, shadow, translateY(-1px)
- Location name (42px, bold, centered)
City, Province (20px, #6d7175, centered)
TWO ACTION CARDS:
Grid: 2 columns (1 on mobile)
Gap: 30px
CARD 1 - VIEW ON MAP:
- Icon:
(64px) - Title: “View on Map” (24px, bold)
- Description: “See this location on Google Maps” (16px, #6d7175)
- Links to: /pages/locations-{slug}-map
- Styling:
- Background: white
- Border: 2px solid #e1e3e5
- Border-radius: 16px
- Padding: 50px 30px
- Text-align: center
- Hover: translateY(-6px), shadow 0 12px 24px, border #5c6ac4
CARD 2 - FULL DETAILS:
- Icon:
(64px) - Title: “Full Details” (24px, bold)
- Description: “View complete address and information” (16px, #6d7175)
- Links to: /pages/locations-{slug}-details
- Same styling as Card 1
=== LEVEL 3A: MAP PAGE ===
URL: /pages/locations-{slug}-map
Created by: Shopify pageCreate mutation
Handle: locations-{slug}-map
Title: {Location Name} - Map
LAYOUT:
- Max-width: 1000px, centered
- Padding: 40px 20px
CONTENT:
- Back button to /pages/locations-{slug}
- Location name (36px, bold, #202223)
- Full address (18px, #6d7175)
- Google Maps iframe:
- Width: 100%
- Height: 500px (400px on mobile)
- Border: 0
- Border-radius: 12px
- Box-shadow: 0 4px 16px rgba(0,0,0,0.1)
- URL: https://maps.google.com/maps?q={encoded-full-address}&output=embed
- Loading: lazy
- Title: “Location map”
=== LEVEL 3B: DETAILS PAGE ===
URL: /pages/locations-{slug}-details
Created by: Shopify pageCreate mutation
Handle: locations-{slug}-details
Title: {Location Name} - Details
LAYOUT:
- Max-width: 800px, centered
- Padding: 40px 20px
CONTENT:
- Back button to /pages/locations-{slug}
- Location name (36px, bold, #202223)
- Address information section:
- Background: #f6f6f7
- Padding: 32px
- Border-radius: 12px
- Border: 1px solid #e1e3e5
- Section title: “Address Information” (22px, bold)
- Fields with labels (16px, line-height 1.6):
- Street: {Address1}
- Suite: {Address2} (if exists)
- City: {City}
- Province: {Province}
- Postal Code: {Zip}
- Country: {Country}
=== DYNAMIC PAGE CREATION ===
SHOPIFY API INTEGRATION:
- Use Admin GraphQL API
- Mutations: pageCreate, pageUpdate, pageDelete
- Check if page exists before creating (query by handle)
- If exists: use pageUpdate with page ID
- If not exists: use pageCreate
- Set isPublished: true for all pages
PAGE CREATION FLOW:
- Merchant uploads CSV or fetches from API
- For each location:
a. Generate unique slug from url_path or name
b. Create overview page (locations-{slug})
c. Create map page (locations-{slug}-map)
d. Create details page (locations-{slug}-details)
e. Store page IDs in metaobject - Create/update main directory page with all locations
- Show success message
HTML GENERATION:
- Build complete HTML with embedded CSS
- Include all styling inline
- Add JavaScript for search (main page only)
- Encode addresses for Google Maps URLs
- Ensure responsive design with media queries
ERROR HANDLING:
- Handle “Handle already taken” errors
- Continue processing if one page fails
- Show clear error messages
- Validate required fields
- Check for duplicate slugs
=== APP INTERFACE ===
LOCATIONS TABLE:
- Columns: Name, Address, Source, URL
- Display format: /pages/locations-{slug}
- Clickable links (open in new tab)
- Copy button for each URL
- Search/filter functionality
- Pagination (25 per page)
- Shows actual Shopify page URLs
CSV UPLOAD:
- Required columns: name, address1, address2, city, province, zip, country, url_path
- Validates all required fields
- Auto-generates slug if url_path empty
- Creates all 4 pages per location
- Shows progress/success message
- Handles errors gracefully
API FETCH:
- Input field for API URL
- Expects JSON array of location objects
- Same validation as CSV
- Creates all pages automatically
- Shows progress/success message
REFRESH MAIN PAGE:
- Button in Settings tab
- Queries ALL locations (not just 25)
- Regenerates main directory page
- Updates /pages/store-locations
- Shows success message
DELETE ALL:
- Confirmation modal
- Deletes all metaobjects
- Deletes all associated Shopify pages
- Shows success message
=== METAOBJECT STRUCTURE ===
Type: sidekick_store_location
Fields:
- name (single_line_text_field, required)
- address1 (single_line_text_field, required)
- address2 (single_line_text_field, optional)
- city (single_line_text_field, required)
- province (single_line_text_field, required)
- zip (single_line_text_field, required)
- country (single_line_text_field, required)
- source (single_line_text_field, required) - “csv” or “api”
- url_path (single_line_text_field, required) - slug
- page_id (single_line_text_field, optional) - Shopify page GID
=== STYLING SYSTEM ===
COLOR PALETTE:
- Primary: #5c6ac4 (blue)
- Text: #202223 (dark)
- Subdued: #6d7175 (gray)
- Background: #f6f6f7 (light gray)
- Border: #e1e3e5 (light gray)
- White: #ffffff
TYPOGRAPHY:
- Font family: -apple-system, BlinkMacSystemFont, ‘Segoe UI’, Roboto, ‘Helvetica Neue’, Arial, sans-serif
- Headings: bold, proper hierarchy
- Body: 16px, line-height 1.6
- Links: #5c6ac4, no underline, hover effect
EFFECTS:
- Border-radius: 8-16px
- Box-shadows: subtle to prominent on hover
- Transitions: 0.2-0.3s ease
- Transform: translateY on hover
- Smooth animations
RESPONSIVE BREAKPOINTS:
- Desktop: >992px
- Tablet: 768-992px
- Mobile: <768px
- Adjust grid, padding, font sizes
=== PERFORMANCE & OPTIMIZATION ===
PAGE CREATION:
- Batch process locations
- Check existing pages before creating
- Reuse existing pages when possible
- Handle timeouts gracefully
- Show progress indicators
SLUG GENERATION:
- Lowercase conversion
- Replace non-alphanumeric with hyphens
- Remove leading/trailing hyphens
- Ensure uniqueness
- Store in metaobject
URL ENCODING:
- Properly encode addresses for Google Maps
- Handle special characters
- Build complete address string
=== SHOPIFY APP STORE REQUIREMENTS ===
APP QUALITY:
- Professional UI/UX
- Clear error messages
- Loading states
- Success confirmations
- Help text and tooltips
MERCHANT EXPERIENCE:
- Easy CSV upload
- Simple API integration
- One-click refresh
- Bulk delete option
- Clear documentation
TECHNICAL REQUIREMENTS:
- Use official Shopify APIs
- Follow API rate limits
- Handle errors gracefully
- Secure data handling
- Proper permissions
=== 100% WORKING REQUIREMENTS ===
MUST WORK:
All pages created successfully via Shopify API
URLs in table show correct format: /pages/locations-{slug}
Clicking URLs opens actual Shopify pages
Main page shows all location cards
Cards clickable and open overview pages
Overview cards open map/details pages
Google Maps displays correctly with proper addresses
All back buttons work
Search functionality works
Responsive on all devices
No timeout errors
Can re-upload without errors
Professional, modern design
Fast performance
Clear error handling
This app creates official Shopify pages dynamically using the Admin API, ensuring all URLs are valid Shopify page URLs that merchants can manage in their admin.