A React application that displays an interactive map of the USA with monument pins and detailed information. Also functions as a searchable catalog for the cultural ecosystem including Persons, Organizations, Programs, and Concepts.
- Interactive USA Map: Displays monuments with custom pins and detailed popups
- API Data Integration: Pulls real-time data from API endpoints
- Searchable Catalog: Browse monuments and cultural ecosystem (persons, organizations, programs, and concepts)
- Interactive Map Integration: Click monument list items to open map tooltips and pan to locations
- Client-side Caching: 5-minute cache for improved performance
- Modern UI: Uses brand colors (#1f3056, #263c59, #c87c35, #fefeff, #e4dfd5, #e5c422)
- Responsive Design: Works on desktop and mobile devices
-
Install Dependencies:
npm install
-
Start Development Server:
npm start
Open http://localhost:3000 to view it in the browser.
-
Build for Production:
npm run build
-
Git commit main for bundle.js deployment
- served via jsdelivr. pulled into webflow page before
</body>tag. hitting mm-proxy served on webflow cloud in MoreMonuments workspace.
<script src="https://cdn.jsdelivr.net/gh/brucestarlove/mm-map@main/dist/bundle.js"></script>- webflow page code embed component:
<div class="react-map-wrapper">
<div id="react-target"></div>
</div>The application currently pulls data from API endpoints served by mm-proxy:
- Monuments:
http://localhost:4321/api/api/monuments.json - Ecosystem:
http://localhost:4321/api/api/ecosystem.json
These endpoints can be configured by setting environment variables:
window.MONUMENTS_API_URL- Override default monuments endpointwindow.ECOSYSTEM_API_URL- Override default ecosystem endpoint
The monuments API returns data with the following structure:
{
"items": [
{
"id": "unique_id",
"fieldData": {
"name": "Monument Name",
"status": "status_id",
"location": "Location Name",
"locationcoords": "latitude,longitude",
"description": "<p>HTML description</p>",
"year": "YYYY",
"height": "Height with units",
"built-by": "Builder Name",
"funded-by": "Funding Source",
"conceptualized-by": "Conceptualizer",
"tags": "comma,separated,tags",
"link-2": "https://external-link.com"
}
}
]
}The ecosystem API returns data with the following structure:
{
"items": [
{
"id": "unique_id",
"fieldData": {
"name": "Entity Name",
"type": "type_id",
"category": "category_id",
"association": "Associated Entity",
"location": "Location",
"website": "https://website.com",
"description": "Description or notes",
"tags": "comma,separated,tags"
}
}
]
}Type Mappings:
- Person, Organization, Program, Concept
Category Mappings:
- Founders, Patrons, Organizations, Programs, Concepts
-
Build and push to GitHub:
npm run bd
-
Use jsDelivr: https://cdn.jsdelivr.net/gh/yourusername/mm-map@main/dist/bundle.js
-
If changes don't appear immediately, purge the jsDelivr cache:
https://purge.jsdelivr.net/gh/brucestarlove/mm-map@main/dist/bundle.jsVisit that URL in your browser to force jsDelivr to refresh the cached file.
-
Update package.json with your S3 bucket name:
"deploy": "aws s3 cp ./dist/bundle.js s3://YOUR_BUCKET_NAME/ --acl public-read"
-
Build and Deploy:
npm run bd
-
Load React Libraries And Target Style in your page's
<head>tag:<!-- React and ReactDOM from CDN -->
-
Load Your Bundle before the closing
</body>tag:<script src="https://cdn.jsdelivr.net/gh/brucestarlove/mm-map@main/dist/bundle.js"></script>
-
Create Target Div where you want the map to appear:
<div id="react-target"></div>
- Font Size Scaling: If the component appears too large, set the Code Embed element's font-size to a smaller value (e.g.,
font-size: 12px). The component uses rem units that scale relative to the parent container's font-size. - Responsive Behavior: The component automatically switches to mobile layout on narrow screens, but you can force this by setting the container font-size smaller.
- Colors: Modify the CSS variables in
src/styles.css - Map Style: Change the tile layer URL in
MonumentMap.js - Data Fields: Update the field mappings in
WebflowCMS.js - UI Components: Customize the layout and components in
MonumentMap.js - API Endpoints: Configure different data sources via
window.MONUMENTS_API_URLandwindow.ECOSYSTEM_API_URL
- Monument Pins: Custom pins for each monument with coordinates
- Popup Tooltips: Detailed information including name, description, year, location, height, and external links
- List Integration: Clicking monument items in the sidebar opens corresponding map tooltips and pans to location
- Non-monument Filtering: Only monuments interact with the map; persons, organizations, programs, and concepts are list-only
- Client-side Caching: 5-minute cache reduces API calls and improves performance
- Error Handling: Graceful degradation when API endpoints are unavailable
- HTML Parsing: Automatically strips HTML tags from descriptions for clean display
- Coordinate Parsing: Handles various coordinate formats including "lat,lng" strings
- Modern browsers with ES6+ support
- Mobile Safari (iOS 10+)
- Chrome (60+)
- Firefox (60+)
- Edge (79+)