Multi-Location Management
Manage hundreds of business locations efficiently with bulk operations, import/export, and centralized control
Overview
ProRank SEO's multi-location management system is designed for businesses with multiple physical locations, from small chains to large franchises. The system provides centralized management with individual location customization, bulk operations, and comprehensive import/export capabilities.
Key Capabilities
Enabling Multi-Location Mode
To enable multi-location management:
- Navigate to ProRank SEO → Local SEO → Schema & Settings
- Find the "Default Schema Settings" section
- Check "Use Multiple Locations"
- Optionally check "All Locations Part of Same Organization" for brand consistency
- Click "Save Settings"
// Setting saved as:
$settings['use_multiple_locations'] = true;
$settings['all_same_organization'] = true;Once enabled, the multi-location management section appears in Schema & Settings, and bulk operations become available in Locations Manager.
Bulk Import Process
Import hundreds of locations at once using CSV or JSON format:
CSV Format
name,street_address,city,state_region,postal_code,country,phone,email,latitude,longitude,is_primary
"Main Office",123 Main St,New York,NY,10001,US,+1-555-0100,main@example.com,40.7128,-74.0060,1
"Brooklyn Branch",456 Park Ave,Brooklyn,NY,11201,US,+1-555-0200,brooklyn@example.com,40.6782,-73.9442,0
"Queens Location",789 Queens Blvd,Queens,NY,11375,US,+1-555-0300,queens@example.com,40.7282,-73.8317,0JSON Format
[
{
"name": "Main Office",
"street_address": "123 Main St",
"city": "New York",
"state_region": "NY",
"postal_code": "10001",
"country": "US",
"phone": "+1-555-0100",
"email": "main@example.com",
"latitude": 40.7128,
"longitude": -74.0060,
"is_primary": true,
"opening_hours": {
"monday": {"open": "09:00", "close": "18:00"},
"tuesday": {"open": "09:00", "close": "18:00"}
}
}
]Import Implementation
The import functionality is handled by the AJAX endpoint:
// LocalSeoMultiLocation.php
public function ajax_import_locations() {
check_ajax_referer('prorank_local_seo', 'nonce');
if (!current_user_can('manage_options')) {
wp_send_json_error(['message' => 'Permission denied']);
}
// Handle file upload
if (!empty($_FILES['import_file'])) {
$file = $_FILES['import_file'];
$content = file_get_contents($file['tmp_name']);
// Detect format (CSV or JSON)
if (strpos($file['name'], '.csv') !== false) {
$locations = $this->parse_csv($content);
} else {
$locations = json_decode($content, true);
}
// Validate and import each location
$results = [
'imported' => 0,
'skipped' => 0,
'errors' => []
];
foreach ($locations as $location) {
if ($this->validate_location($location)) {
$this->add_location($location);
$results['imported']++;
} else {
$results['skipped']++;
}
}
wp_send_json_success($results);
}
}Bulk Operations
Perform operations on all locations simultaneously:
Validate All
Checks all locations for:
- • Missing required fields
- • Invalid geo-coordinates
- • Duplicate names
- • Schema compliance
Endpoint: prorank_validate_location
AI Optimize All
Generates for each location:
- • SEO-optimized descriptions
- • Local keywords
- • Voice search phrases
- • Meta descriptions
Endpoint: prorank_generate_ai_description
Export All
Downloads complete dataset:
- • All location data
- • Opening hours
- • AI-generated content
- • Optimization scores
Endpoint: prorank_export_locations
Generate Schema
Creates schema markup for:
- • LocalBusiness array
- • Individual location pages
- • Organization with departments
- • Service area businesses
Output via wp_head hook
Batch Processing
Large operations are processed in batches to prevent timeouts:
// Batch processing implementation
function processLocationsInBatches(locations, batchSize = 10) {
let processed = 0;
function processBatch() {
const batch = locations.slice(processed, processed + batchSize);
$.ajax({
url: prorankLocalSeo.ajaxUrl,
type: 'POST',
data: {
action: 'prorank_process_batch',
locations: batch,
nonce: prorankLocalSeo.nonce
},
success: function(response) {
processed += batch.length;
updateProgress(processed, locations.length);
if (processed < locations.length) {
setTimeout(processBatch, 500); // Process next batch
} else {
showCompletionMessage();
}
}
});
}
processBatch();
}Location Relationships
Define relationships between locations for better schema representation:
Hierarchy Options
Primary Location
Mark one location as primary (headquarters). This location's data is used as the default organization information in schema markup.
$location['is_primary'] = true; // Only one allowedSame Organization
When enabled, all locations are marked as departments of the same organization, improving brand recognition in search results.
{
"@type": "Organization",
"department": [
{"@type": "LocalBusiness", "name": "Location 1"},
{"@type": "LocalBusiness", "name": "Location 2"}
]
}REST API Endpoints
Access location data programmatically via REST API:
// Registration in LocalSeoMultiLocation.php
public function register_rest_routes() {
register_rest_route('prorank/v1', '/locations', [
'methods' => 'GET',
'callback' => [$this, 'rest_get_locations'],
'permission_callback' => '__return_true'
]);
register_rest_route('prorank/v1', '/locations/(?P<id>d+)', [
'methods' => 'GET',
'callback' => [$this, 'rest_get_location'],
'permission_callback' => '__return_true'
]);
}Available Endpoints
GET /wp-json/prorank/v1/locations- Get all locationsGET /wp-json/prorank/v1/locations/{id}- Get specific locationPOST /wp-json/prorank/v1/locations- Add new location (requires auth)PUT /wp-json/prorank/v1/locations/{id}- Update location (requires auth)DELETE /wp-json/prorank/v1/locations/{id}- Delete location (requires auth)
Performance Optimization
The system is optimized for handling large numbers of locations:
Data Storage
- • Serialized array in options table
- • Indexed by unique location ID
- • Cached for fast retrieval
- • Transient cache for schema output
Frontend Optimization
- • Virtual scrolling for large lists
- • Client-side search and filtering
- • Lazy loading of location details
- • Debounced search input
Best Practices
Recommendations
- Start with a CSV template - export a single location first to get the format
- Always validate after bulk import to catch any issues
- Use consistent NAP format across all locations
- Add geo-coordinates for all locations (use batch geocoding tools)
- Regular exports for backup purposes
- Use AI optimization after adding new locations