Refactor DEA detail page to server component and add public API v1#125
Merged
Refactor DEA detail page to server component and add public API v1#125
Conversation
…N-LD - Add comprehensive metadata to layout.tsx: Open Graph tags, Twitter Cards, keywords, canonical URL, and Google bot directives - Create robots.ts to control crawler access (block /admin, /api, /import, /org) - Create sitemap.ts with all public pages and priorities - Add JSON-LD structured data (WebApplication schema) for rich search results - Enhance site.webmanifest with description, start_url, scope, lang, categories The og-image.png file must be placed in public/ separately. https://claude.ai/code/session_01XR9dGVxVAS4D3XutEUnhk9
… Search Console keywords - Split /dea/[id] into server component (generateMetadata) + client component for rich sharing previews (noindex, follow for SEO) - Create /desfibriladores page listing all cities with AED counts - Create /desfibriladores/[city] pages with per-city AED listings, grouped by district, with SEO-optimized content - Add metadata layout for /dea/new-simple - Update keywords based on Search Console data (mapa dea, desfibriladores cerca de mi, dea near me, AED locator, etc.) - Set up i18n foundation: config, dictionary loader, and translation files for ES, EN, FR, DE, PT - Add hreflang alternate links in root layout metadata - Make sitemap.ts dynamic: fetches city pages from database - Remove Google verification env var (already verified via DNS) https://claude.ai/code/session_01XR9dGVxVAS4D3XutEUnhk9
…in manifest Public API endpoints (rate limited 60 req/min, no auth required): - GET /api/v1/aeds/nearby - Find nearest AEDs by coordinates (PostGIS) - GET /api/v1/aeds/:id - Get AED details by ID - GET /api/v1/aeds/city/:city - List AEDs by city (paginated) - GET /api/v1/aeds/stats - Global statistics (totals, top cities) - GET /api/v1/openapi.json - OpenAPI 3.1 specification Supporting files for LLM/AI discoverability: - /llms.txt - Summary for LLM consumption - /llms-full.txt - Full API context with examples - /.well-known/ai-plugin.json - AI plugin manifest (ChatGPT/etc.) - /api/docs - Human-readable API documentation page Infrastructure: - Rate limiter for public API (60/min per IP) in rate-limit-public-api.ts - Middleware updated to allow /api/v1/ as public path - robots.txt updated to allow /api/docs and /api/v1/openapi.json - Sitemap updated to include /api/docs page - All responses include CORS headers and cache control https://claude.ai/code/session_01XR9dGVxVAS4D3XutEUnhk9
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Structured issue for creating iframe-embeddable maps for third parties: installers, maintenance companies, municipalities, and organizations. https://claude.ai/code/session_01XR9dGVxVAS4D3XutEUnhk9
…tions)
Raw SQL queries were using Prisma model names ("Aed", "AedLocation") instead
of the actual PostgreSQL table names (aeds, aed_locations) mapped via @@Map().
This caused P2010 errors during build: 'relation "Aed" does not exist'.
Also removes the .github/ISSUES file that was committed by mistake.
https://claude.ai/code/session_01XR9dGVxVAS4D3XutEUnhk9
Temporary file for issue creation - to be removed after copying content. https://claude.ai/code/session_01XR9dGVxVAS4D3XutEUnhk9
- Add FAQPage JSON-LD to homepage with 5 Q&As (DeaMap, how it works, why AEDs matter, how to add one, public API) for Google rich snippets - Add BreadcrumbList JSON-LD to city pages (DeaMap > Desfibriladores > City) - Add internal links in footer: "Desfibriladores por ciudad" and "API pública" - Improve 404 page with useful links: map, city search, add AED - Update copyright year to 2024-2026 https://claude.ai/code/session_01XR9dGVxVAS4D3XutEUnhk9
- Extract footer from homepage into reusable Footer component in layout - All pages now consistently show navigation + footer - City pages load 50 AEDs per page instead of all at once (fixes performance for cities like Madrid with 5000+ entries) - Use COUNT queries for metadata instead of loading all records - Add district overview section for large cities - Show pagination controls with page numbers https://claude.ai/code/session_01XR9dGVxVAS4D3XutEUnhk9
…temap - Fix pagination canonicals: page 2+ now self-referential instead of pointing to page 1 - Remove hreflang declarations (app is Spanish-only, was confusing search engines) - Add noindex robots to auth pages (login, register, forgot/reset password) and 404 - Remove auth and legal pages from sitemap - Add paginated city URLs to sitemap with proper priorities - Add Place + GeoCoordinates JSON-LD structured data to individual DEA pages for better sharing and AI understanding https://claude.ai/code/session_01XR9dGVxVAS4D3XutEUnhk9
- Pre-render top 100 cities by AED count at build time - dynamicParams=true allows unlisted cities on-demand - Revalidate every hour (ISR) so pages stay fresh - Also add revalidate to /desfibriladores index page https://claude.ai/code/session_01XR9dGVxVAS4D3XutEUnhk9
- Rename route folder from desfibriladores/ to locations/ - Update all internal links, sitemap, breadcrumbs, and footer - Add permanent 301 redirects in next.config.ts for old URLs - Neutral English path works better for future internationalization https://claude.ai/code/session_01XR9dGVxVAS4D3XutEUnhk9
latitude and longitude are on the Aed model, not AedLocation. https://claude.ai/code/session_01XR9dGVxVAS4D3XutEUnhk9
Wrap query in try/catch so build succeeds without a database connection (CI). ISR will populate data on first request. https://claude.ai/code/session_01XR9dGVxVAS4D3XutEUnhk9
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR introduces significant architectural improvements and new public API endpoints to DeaMap. The main changes include converting the DEA detail page to a server component for better SEO and performance, implementing a comprehensive public REST API v1, and adding new public-facing pages for city-based AED browsing.
Key Changes
Architecture & Performance
src/app/dea/[id]/page.tsxfrom a client component to a server component that fetches data server-side and generates proper metadata for SEODeaDetailClient.tsxcomponentfilterAedByPublicationMode()utility to respect publication settings on both server and clientPublic API v1 (New)
GET /api/v1/aeds/nearby): Find nearest defibrillators using PostGIS spatial queries with configurable radius and limitGET /api/v1/aeds/{id}): Retrieve full AED information with publication mode filteringGET /api/v1/aeds/city/{city}): Get all AEDs in a city with pagination supportGET /api/v1/aeds/stats): Global statistics including total AEDs and top citiesGET /api/v1/openapi.json): Full OpenAPI 3.1 spec for API documentationPublic Pages (New)
/desfibriladores): Browse all cities with AED counts/desfibriladores/[city]): View all AEDs in a specific city, grouped by district/api/docs): Comprehensive API documentation with examples and quick start guideSEO & Metadata
Internationalization (New)
getDictionary()utility for loading locale-specific contentDocumentation
llms.txt,llms-full.txt) for AI assistant integrationImplementation Details
publication_modefield to control visibility across public endpointsST_DWithinfor efficient geographic distance calculationshttps://claude.ai/code/session_01XR9dGVxVAS4D3XutEUnhk9