diff --git a/CHANGELOG.md b/CHANGELOG.md index f97a85afd..3170ca26d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ # CHANGELOG +## 2026-11-10 - One commercial spot per page; Juárez dentist crossing guide (draft) + +- Rule: a page shows a sponsor card or a network ad, never both. On the five El Paso/Juárez crossing pages and on sponsored guides, the sponsor replaces the Adsterra unit. +- New guide (EN and ES): going to a dentist in Ciudad Juárez from El Paso or New Mexico. Covers which bridge to check, documents, how to look up a dentist's cédula, and timing the return. Agency rules link to CBP, SEP and CONAMED. No prices or treatment advice. The sponsor card sits in the guide under the vetting checklist via ``. +- Medication guides place the sponsor with `` after the current-wait links. +- Sponsor links have distinct accessible names (for example "WhatsApp: "). +- Checks: full `npm test` passes after a prerendered build; entry bundle 61.92 KB gzip. Headless Chrome 390px: sponsored pages show 1 card and 0 ads; San Ysidro and the SENTRI guide show 0 cards and 1 ad. + +## 2026-11-10 - Sponsored listings, first sponsor (draft) + +- New `SponsoredCard` and `src/lib/sponsors.js`: one labeled sponsor per placement, set by port number or guide slug, with optional `since`/`until` dates. Each card is marked Sponsored/Patrocinado and says Border Pulse has not evaluated the business's care. +- First sponsor: Constandse Esthetic & Dent (Ciudad Juárez dentist), on the five El Paso/Juárez crossing pages (above the ad) and on both medication guides (under the current-wait links). Links carry UTM tags; clicks log `sponsor-click` with sponsor, placement and action (site or WhatsApp), no free text. +- Privacy notice (EN/ES) now says clicks on sponsored listings are counted with Umami and that sponsored listings are labeled placements from local businesses. +- Checks: full `npm test` passes after a prerendered build; entry bundle 62.02 KB gzip (budget 62.25). Headless Chrome 390px: card on PDN and both guides, none on San Ysidro, click logs the event, no overflow. +- Open: the site link points at the clinic's preview deployment until its own domain is live. ## 2026-11-10 - Crossing titles and descriptions match how people search (draft) - Crossing page titles now follow the query shape from Search Console: " border wait times today" (EN) and "Tiempos de espera en hoy" (ES). Bridges and ports of entry use the name people type: "Anzalduas International Bridge (Hidalgo/Pharr)", "Santa Teresa Port of Entry", "Andrade (Los Algodones)", "Eagle Pass International Bridge II" and others. diff --git a/DECISIONS.md b/DECISIONS.md index 840789c64..d3f61a024 100644 --- a/DECISIONS.md +++ b/DECISIONS.md @@ -577,3 +577,7 @@ Adsterra reported 21 impressions and $0.03 for Nov 5 to 9 from the single home-p ## 2026-11-10 - Light-mode slate-500 is one notch darker for AA contrast Stock `slate-500` (#62748e) measured 4.47:1 on the light page background, just under 4.5:1, on every page. Light mode overrides `--color-slate-500` to #5e7088 (4.75:1) instead of editing hundreds of class names; `.dark` restores the stock value so dark mode does not lose contrast. + +## 2026-11-10 - One commercial spot per page + +A page carries a sponsor card or a network ad, never both, and always below the answer. A sponsor replaces the Adsterra unit on its pages. Sponsors are configured in `src/lib/sponsors.js`, one per port or guide, always labeled Sponsored/Patrocinado with the "has not evaluated" line. Sponsor copy states facts only (name, city, links); no medical or price claims in Border Pulse's voice. diff --git a/ROADMAP.md b/ROADMAP.md index 9e6c01164..f4439e57a 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -339,3 +339,10 @@ Snapshot of features live on borderpulse.com today. - Bounded dashboard ad-slot diagnostics through existing Umami: script/DOM/ container visibility stages only, not billed impressions or revenue. Actual ad-network totals still require publisher reports. + +## Backlog: sponsored placements (added 2026-11-10) + +- Pharmacy sponsor for the medication guides (highest-traffic slot). Not being pitched yet; needs a trusted contact and a vetting pass first. +- City guides as sponsor inventory: Tijuana, Los Algodones, Nuevo Progreso, Nogales. One featured business per category section. +- Self-serve "feature your business" page, after 2 to 3 paying sponsors and a real click number to show. +- Swap the first sponsor's link from the preview deployment to its own address once that site launches. diff --git a/public/og/blog/dentist-in-juarez-from-el-paso-new-mexico.png b/public/og/blog/dentist-in-juarez-from-el-paso-new-mexico.png new file mode 100644 index 000000000..6901ebfa5 Binary files /dev/null and b/public/og/blog/dentist-in-juarez-from-el-paso-new-mexico.png differ diff --git a/public/og/blog/dentista-en-juarez-desde-el-paso-nuevo-mexico.png b/public/og/blog/dentista-en-juarez-desde-el-paso-nuevo-mexico.png new file mode 100644 index 000000000..600f37adf Binary files /dev/null and b/public/og/blog/dentista-en-juarez-desde-el-paso-nuevo-mexico.png differ diff --git a/src/components/blog/FeaturedSponsor.jsx b/src/components/blog/FeaturedSponsor.jsx new file mode 100644 index 000000000..015261dd5 --- /dev/null +++ b/src/components/blog/FeaturedSponsor.jsx @@ -0,0 +1,12 @@ +import { useContext } from 'react'; +import { useParams } from 'react-router-dom'; +import { LangContext } from '@/lib/LangContext'; +import SponsoredCard from '@/components/sponsors/SponsoredCard'; +import { sponsorForGuide } from '@/lib/sponsors'; + +// Places this guide's sponsor (if any) where the article calls for it. +export default function FeaturedSponsor() { + const lang = useContext(LangContext) || 'en'; + const { slug } = useParams(); + return ; +} diff --git a/src/components/blog/InArticleAd.jsx b/src/components/blog/InArticleAd.jsx index 65d83fe9f..b29089a82 100644 --- a/src/components/blog/InArticleAd.jsx +++ b/src/components/blog/InArticleAd.jsx @@ -1,11 +1,16 @@ import { useContext } from 'react'; +import { useParams } from 'react-router-dom'; import AdsterraBanner from '@/components/ads/AdsterraBanner'; import { LangContext } from '@/lib/LangContext'; +import { sponsorForGuide } from '@/lib/sponsors'; // Mid-article ad for long guides. A post that uses it sets `inArticleAd: true` // in frontmatter so BlogPost skips its end-of-post slot: one container per page. +// One commercial spot per page: a guide with a sponsor shows no network ad. export default function InArticleAd() { const lang = useContext(LangContext) || 'en'; + const { slug } = useParams(); + if (sponsorForGuide(slug)) return null; return (
diff --git a/src/components/blog/MdxComponents.jsx b/src/components/blog/MdxComponents.jsx index e62a925aa..70bc79329 100644 --- a/src/components/blog/MdxComponents.jsx +++ b/src/components/blog/MdxComponents.jsx @@ -4,6 +4,7 @@ import BestTimeChart from './BestTimeChart'; import CrossingRankings from './CrossingRankings'; import InArticleAd from './InArticleAd'; import CrossingWaitLinks from './CrossingWaitLinks'; +import FeaturedSponsor from './FeaturedSponsor'; function CrossingLink({ slug, children }) { return ( @@ -20,6 +21,7 @@ export const mdxComponents = { CrossingLink, InArticleAd, CrossingWaitLinks, + FeaturedSponsor, a: (props) => { const isExternal = /^https?:\/\//.test(props.href || ''); if (isExternal) { diff --git a/src/components/sponsors/SponsoredCard.jsx b/src/components/sponsors/SponsoredCard.jsx new file mode 100644 index 000000000..6923cdb5f --- /dev/null +++ b/src/components/sponsors/SponsoredCard.jsx @@ -0,0 +1,51 @@ +import { ExternalLink, MessageCircle } from 'lucide-react'; +import { sponsorUrl } from '@/lib/sponsors'; +import { track } from '@/lib/analytics'; + +// A labeled paid placement. Clicks log `sponsor-click` (sponsor id, placement, +// action) so each sponsor gets a monthly count. No free text is sent. +export default function SponsoredCard({ sponsor, placement, language = 'en' }) { + if (!sponsor) return null; + const es = language === 'es'; + const log = action => track('sponsor-click', { sponsor: sponsor.id, placement, action }); + return ( + + ); +} diff --git a/src/content/blog/bringing-prescription-medication-back-from-mexico.mdx b/src/content/blog/bringing-prescription-medication-back-from-mexico.mdx index ea15a488e..a098520c0 100644 --- a/src/content/blog/bringing-prescription-medication-back-from-mexico.mdx +++ b/src/content/blog/bringing-prescription-medication-back-from-mexico.mdx @@ -36,6 +36,8 @@ When in doubt, fill the U.S. prescription on the U.S. side and use the Mexican t + + ## The core rule For most prescription medications, CBP applies a personal-use standard: a small quantity (commonly described as up to a 90-day supply per medication) of an FDA-approved drug, with a valid prescription from a licensed practitioner, may be brought back into the U.S. for the importer's personal use. The drug must be declared at the port of entry on request. diff --git a/src/content/blog/dentist-in-juarez-from-el-paso-new-mexico.mdx b/src/content/blog/dentist-in-juarez-from-el-paso-new-mexico.mdx new file mode 100644 index 000000000..9781e213f --- /dev/null +++ b/src/content/blog/dentist-in-juarez-from-el-paso-new-mexico.mdx @@ -0,0 +1,95 @@ +--- +title: "Going to a dentist in Ciudad Juárez from El Paso or New Mexico: a crossing guide" +description: "Which bridge to use, what to bring, how to check a dentist's license in Mexico, and how to time the trip back. For patients from El Paso, Las Cruces and southern New Mexico." +slug: dentist-in-juarez-from-el-paso-new-mexico +date: "2026-11-10" +author: sebastian +pillar: crossing-guides +lang: en +tags: + - juarez + - el-paso + - new-mexico + - dental + - medical-tourism + - paso-del-norte +translationKey: juarez-dentist-crossing-guide +hero: /og/blog/dentist-in-juarez-from-el-paso-new-mexico.png +relatedCrossings: + - "240202" + - "240201" + - "240104" + - "240801" +officialSources: + - label: "CBP Border Wait Times (live CBP data)" + url: "https://bwt.cbp.gov/" + - label: "CBP: Western Hemisphere Travel Initiative documents" + url: "https://www.cbp.gov/travel/us-citizens/western-hemisphere-travel-initiative" + - label: "SEP: Registro Nacional de Profesionistas (license lookup)" + url: "https://www.cedulaprofesional.sep.gob.mx/" + - label: "CONAMED: medical arbitration commission" + url: "https://www.gob.mx/conamed" +--- + +People from El Paso, Las Cruces and southern New Mexico cross into Ciudad Juárez for dental work as a day trip. The dentistry is the clinic's job. This guide covers the part around it: which bridge to use, what to bring, how to check a dentist before you book, and how to time the trip back. + +## The short version + +- **Pick the bridge by where you start and how you travel.** Walking from downtown El Paso: Paso del Norte. Driving: Bridge of the Americas or Ysleta-Zaragoza. Coming from New Mexico: look at Santa Teresa. +- **Bring a document CBP accepts for re-entry by land.** CBP lists them under the [Western Hemisphere Travel Initiative](https://www.cbp.gov/travel/us-citizens/western-hemisphere-travel-initiative). +- **Check the dentist's license before you book.** Mexico's education ministry runs a public [license lookup](https://www.cedulaprofesional.sep.gob.mx/). +- **Plan the return, not just the appointment.** The wait to come back is the part that varies. + + + +## Which bridge to use + +| Starting from | Crossing to check first | Why | +|---|---|---| +| Downtown El Paso, on foot | [Paso del Norte](/crossing/el-paso-paso-del-norte-pdn/) | It connects downtown El Paso to downtown Juárez, and CBP reports a pedestrian lane there. | +| Central El Paso, driving | [Bridge of the Americas](/crossing/el-paso-bridge-of-the-americas-bota/) | Known locally as Puente Libre. It handles passenger vehicles, including larger ones. | +| East El Paso, driving | [Ysleta-Zaragoza](/crossing/el-paso-ysleta/) | It is the eastern bridge, so it can save a drive across town. | +| Las Cruces or southern New Mexico | [Santa Teresa](/crossing/santa-teresa-santa-teresa-port-of-entry/) | It sits west of El Paso in New Mexico. Compare it with the El Paso bridges before you leave. | + +Ask the clinic which bridge is closest to them and whether they offer a pickup. Some Juárez clinics do, and it changes which bridge makes sense. + +If you are choosing between the two central bridges, the hour-by-hour comparison is in [Paso del Norte vs Bridge of the Americas](/blog/paso-del-norte-vs-bridge-of-the-americas/). + +## What to bring + +- **Your travel document.** U.S. citizens returning by land need a document CBP accepts, such as a U.S. passport book or passport card. The full list is on [CBP's page](https://www.cbp.gov/travel/us-citizens/western-hemisphere-travel-initiative). +- **Your dental records.** Recent X-rays and a list of the medications you take help the dentist plan before you sit down. +- **A way to pay that the clinic confirmed.** Ask ahead whether they take cards, dollars or pesos. +- **The clinic's address and phone number on paper.** Phone service can drop near the bridges. + +## How to check a dentist before you book + +Border Pulse does not rate clinics. These are checks you can do yourself. + +1. **Look up the license.** Every dentist practicing in Mexico has a professional license number (cédula profesional). Ask for it and search it in the [public registry](https://www.cedulaprofesional.sep.gob.mx/). A specialist, such as an implant or oral rehabilitation dentist, has a separate specialty license. Ask for that one too. +2. **Ask for a written treatment plan and an itemized quote.** It should say what is included: X-rays, the implant, the abutment, the crown, follow-up visits. +3. **Ask what happens if something goes wrong after you are home.** Who do you call, is there a warranty, and does a fix mean another trip? +4. **Ask how many visits the work takes.** Implants and full restorations usually take more than one trip, so the crossing becomes part of the cost. +5. **Know where complaints go.** Mexico's medical arbitration commission, [CONAMED](https://www.gob.mx/conamed), handles disputes between patients and health providers. + + + +## Timing the trip back + +The appointment has a fixed time. The return wait does not. The chart shows the typical northbound wait at Paso del Norte by day and hour, from the last 30 days of CBP reports. + + + +- **Book around the quiet hours** the chart shows, when you have a choice. +- **Check the current wait before you leave the clinic**, not when you reach the line. Each crossing page shows the time CBP last reported. +- **Have a second bridge in mind.** If one is backed up, another may be shorter. + +The chart is history, not a forecast. Holidays, weather and lane closures change it. + +## Bringing medication back + +If the dentist prescribes something, the rules for bringing it into the U.S. are in [Bringing prescription medication back from Mexico](/blog/bringing-prescription-medication-back-from-mexico/). Declare what you carry. + +## How this guide was made + +Wait patterns come from the official [CBP Border Wait Times](https://bwt.cbp.gov/) feed, stored by Border Pulse and summarized as medians. Document and licensing points link to the agency that sets them. This guide does not give medical advice or recommend a treatment. diff --git a/src/content/blog/dentista-en-juarez-desde-el-paso-nuevo-mexico.mdx b/src/content/blog/dentista-en-juarez-desde-el-paso-nuevo-mexico.mdx new file mode 100644 index 000000000..2e2d5495c --- /dev/null +++ b/src/content/blog/dentista-en-juarez-desde-el-paso-nuevo-mexico.mdx @@ -0,0 +1,95 @@ +--- +title: "Ir al dentista en Ciudad Juárez desde El Paso o Nuevo México: guía de cruce" +description: "Qué puente usar, qué llevar, cómo verificar la cédula de un dentista y cómo planear el regreso. Para pacientes de El Paso, Las Cruces y el sur de Nuevo México." +slug: dentista-en-juarez-desde-el-paso-nuevo-mexico +date: "2026-11-10" +author: sebastian +pillar: crossing-guides +lang: es +tags: + - juarez + - el-paso + - new-mexico + - dental + - medical-tourism + - paso-del-norte +translationKey: juarez-dentist-crossing-guide +hero: /og/blog/dentista-en-juarez-desde-el-paso-nuevo-mexico.png +relatedCrossings: + - "240202" + - "240201" + - "240104" + - "240801" +officialSources: + - label: "CBP Tiempos de Espera (datos en vivo de CBP)" + url: "https://bwt.cbp.gov/" + - label: "CBP: documentos de la Iniciativa de Viajes del Hemisferio Occidental" + url: "https://www.cbp.gov/travel/us-citizens/western-hemisphere-travel-initiative" + - label: "SEP: Registro Nacional de Profesionistas (consulta de cédulas)" + url: "https://www.cedulaprofesional.sep.gob.mx/" + - label: "CONAMED: Comisión Nacional de Arbitraje Médico" + url: "https://www.gob.mx/conamed" +--- + +Mucha gente de El Paso, Las Cruces y el sur de Nuevo México cruza a Ciudad Juárez para atenderse con el dentista y regresa el mismo día. El trabajo dental le toca a la clínica. Esta guía cubre lo demás: qué puente usar, qué llevar, cómo revisar a un dentista antes de agendar y cómo planear el regreso. + +## En resumen + +- **Elige el puente según de dónde sales y cómo viajas.** A pie desde el centro de El Paso: Paso del Norte (Santa Fe). En auto: Puente Libre o Zaragoza. Desde Nuevo México: revisa Santa Teresa. +- **Lleva un documento que CBP acepte para regresar por tierra.** CBP los enlista en la [Iniciativa de Viajes del Hemisferio Occidental](https://www.cbp.gov/travel/us-citizens/western-hemisphere-travel-initiative). +- **Verifica la cédula del dentista antes de agendar.** La SEP tiene una [consulta pública de cédulas](https://www.cedulaprofesional.sep.gob.mx/). +- **Planea el regreso, no solo la cita.** La espera de vuelta es lo que más cambia. + + + +## Qué puente usar + +| Si sales de | Cruce para revisar primero | Por qué | +|---|---|---| +| Centro de El Paso, a pie | [Santa Fe · Paso del Norte](/crossing/el-paso-paso-del-norte-pdn/) | Conecta el centro de El Paso con el centro de Juárez, y CBP reporta ahí un carril peatonal. | +| Zona central de El Paso, en auto | [Puente Libre](/crossing/el-paso-bridge-of-the-americas-bota/) | Es el Puente de las Américas. Recibe vehículos de pasajeros, incluidos los más grandes. | +| Este de El Paso, en auto | [Zaragoza · Ysleta](/crossing/el-paso-ysleta/) | Es el puente del lado este, así que puede ahorrarte cruzar la ciudad. | +| Las Cruces o el sur de Nuevo México | [Santa Teresa · San Jerónimo](/crossing/santa-teresa-santa-teresa-port-of-entry/) | Está al oeste de El Paso, en Nuevo México. Compáralo con los puentes de El Paso antes de salir. | + +Pregunta a la clínica qué puente les queda más cerca y si ofrecen traslado. Algunas clínicas de Juárez lo ofrecen, y eso cambia qué puente conviene. + +Si dudas entre los dos puentes centrales, la comparación hora por hora está en [Paso del Norte vs Puente de las Américas](/blog/paso-del-norte-vs-puente-de-las-americas/). + +## Qué llevar + +- **Tu documento de viaje.** Los ciudadanos de EE.UU. que regresan por tierra necesitan un documento que CBP acepte, como el pasaporte o la tarjeta de pasaporte. La lista completa está en la [página de CBP](https://www.cbp.gov/travel/us-citizens/western-hemisphere-travel-initiative). +- **Tu historial dental.** Radiografías recientes y la lista de medicamentos que tomas ayudan al dentista a planear antes de empezar. +- **Una forma de pago que la clínica haya confirmado.** Pregunta antes si aceptan tarjeta, dólares o pesos. +- **La dirección y el teléfono de la clínica en papel.** La señal del celular puede fallar cerca de los puentes. + +## Cómo revisar a un dentista antes de agendar + +Border Pulse no califica clínicas. Estas son revisiones que puedes hacer por tu cuenta. + +1. **Consulta la cédula.** Todo dentista que ejerce en México tiene una cédula profesional. Pídela y búscala en el [registro público](https://www.cedulaprofesional.sep.gob.mx/). Un especialista, por ejemplo en implantes o rehabilitación oral, tiene además una cédula de especialidad. Pide esa también. +2. **Pide un plan de tratamiento por escrito y un presupuesto desglosado.** Debe decir qué incluye: radiografías, implante, pilar, corona y citas de seguimiento. +3. **Pregunta qué pasa si algo sale mal cuando ya estés en casa.** A quién llamas, si hay garantía y si la corrección implica otro viaje. +4. **Pregunta cuántas visitas requiere el trabajo.** Los implantes y las rehabilitaciones completas suelen necesitar más de un viaje, así que el cruce es parte del costo. +5. **Ten presente a dónde van las quejas.** La [CONAMED](https://www.gob.mx/conamed) atiende controversias entre pacientes y prestadores de servicios de salud. + + + +## Cómo planear el regreso + +La cita tiene hora fija. La espera de regreso no. La gráfica muestra la espera típica hacia el norte en Paso del Norte por día y hora, con los últimos 30 días de reportes de CBP. + + + +- **Agenda cerca de las horas tranquilas** que muestra la gráfica, cuando puedas elegir. +- **Revisa la espera actual antes de salir de la clínica**, no al llegar a la fila. Cada página de cruce muestra la hora del último reporte de CBP. +- **Ten un segundo puente en mente.** Si uno está saturado, otro puede estar más corto. + +La gráfica es historial, no un pronóstico. Los días festivos, el clima y los cierres de carriles la cambian. + +## Traer medicamentos de regreso + +Si el dentista te receta algo, las reglas para entrarlo a EE.UU. están en [Traer medicamentos con receta de México](/blog/traer-medicamentos-con-receta-de-mexico/). Declara lo que lleves. + +## Cómo se hizo esta guía + +Los patrones de espera vienen del feed oficial de [Tiempos de Espera de CBP](https://bwt.cbp.gov/), guardado por Border Pulse y resumido en medianas. Los puntos sobre documentos y cédulas enlazan a la dependencia que los define. Esta guía no da consejo médico ni recomienda un tratamiento. diff --git a/src/content/blog/traer-medicamentos-con-receta-de-mexico.mdx b/src/content/blog/traer-medicamentos-con-receta-de-mexico.mdx index ab3d11ee7..baf0d75bd 100644 --- a/src/content/blog/traer-medicamentos-con-receta-de-mexico.mdx +++ b/src/content/blog/traer-medicamentos-con-receta-de-mexico.mdx @@ -36,6 +36,8 @@ Cuando hay duda, surte la receta de EE.UU. del lado de EE.UU. y usa el viaje a M + + ## La regla central Para la mayoría de los medicamentos con receta, CBP aplica un estándar de uso personal: una cantidad pequeña (comúnmente descrita como hasta 90 días por medicamento) de un medicamento aprobado por la FDA, con receta válida de un profesional licenciado, se puede traer de regreso a EE.UU. para uso personal del importador. El medicamento debe declararse en el puerto de entrada cuando se solicite. diff --git a/src/lib/analytics.js b/src/lib/analytics.js index cb38d1277..875e71ef6 100644 --- a/src/lib/analytics.js +++ b/src/lib/analytics.js @@ -29,6 +29,9 @@ // blog-share guide distribution; slug and method=copy|whatsapp // blog-to-waits guide reader opening current waits; crossing + placement=top for the in-guide links // +// Sponsors: +// sponsor-click sponsor id, placement (crossing- | guide-), action=site|whatsapp +// // Diagnostics (not audited ad-network statistics): // ad-slot-diagnostic slot=dashboard-native; state=script-ready|script-error| // container-populated|slot-visible. At most once per diff --git a/src/lib/privacyParagraphs.js b/src/lib/privacyParagraphs.js index 85c3b8f54..9a267712f 100644 --- a/src/lib/privacyParagraphs.js +++ b/src/lib/privacyParagraphs.js @@ -9,8 +9,8 @@ const paragraphs = { "en": "Border Pulse works without an account. Language, theme, and filter preferences may be saved in your browser’s local storage. Wait times come from the public U.S. Customs and Border Protection feed." }, "analytics": { - "es": "Las vistas de página se miden con Umami, una analítica sin cookies. Border Pulse no recibe documentos de viaje ni ubicación precisa.", - "en": "Page views are measured with Umami, a cookieless analytics service. Border Pulse does not receive travel documents or precise location." + "es": "Las vistas de página y los clics en anuncios patrocinados se miden con Umami, una analítica sin cookies. Los anuncios patrocinados son espacios de negocios locales y están marcados como tales. Border Pulse no recibe documentos de viaje ni ubicación precisa.", + "en": "Page views and clicks on sponsored listings are measured with Umami, a cookieless analytics service. Sponsored listings are placements from local businesses and are labeled as such. Border Pulse does not receive travel documents or precise location." }, "adsterra": { "es": "Border Pulse muestra anuncios de terceros para ayudar a mantener la plataforma. El panel principal, las páginas de cruces y las guías cargan el script publicitario de Adsterra; los anuncios pueden no mostrarse si el servicio o el navegador los bloquea.", diff --git a/src/lib/sponsors.js b/src/lib/sponsors.js new file mode 100644 index 000000000..d613b6b3c --- /dev/null +++ b/src/lib/sponsors.js @@ -0,0 +1,45 @@ +// Sponsored placements from local businesses. One sponsor per placement; every card +// is labeled Sponsored. Keep entries factual: name, city, links. No medical or +// price claims in Border Pulse's voice; the business owns its own claims. +// Remove an entry (or set `until`) to end a placement. +export const SPONSORS = [ + { + id: 'constandse-dental', + name: 'Constandse Esthetic & Dent', + category: { en: 'Dentist', es: 'Dentista' }, + city: 'Ciudad Juárez', + blurb: { + en: 'Dental clinic in Ciudad Juárez, a short trip from the El Paso bridges.', + es: 'Clínica dental en Ciudad Juárez, a poca distancia de los puentes de El Paso.', + }, + url: 'https://dr-constandse-preview.vercel.app/', + whatsapp: '19153007751', + // Ciudad Juárez crossings: PDN, BOTA, Ysleta, Stanton DCL, El Paso (combined). + ports: ['240202', '240201', '240104', '240204', '240221'], + guides: [ + 'bringing-prescription-medication-back-from-mexico', 'traer-medicamentos-con-receta-de-mexico', + 'dentist-in-juarez-from-el-paso-new-mexico', 'dentista-en-juarez-desde-el-paso-nuevo-mexico', + ], + since: '2026-11-10', + until: null, + }, +]; + +const active = (s, today) => (!s.since || s.since <= today) && (!s.until || today <= s.until); +const todayIso = () => new Date().toISOString().slice(0, 10); + +export function sponsorForPort(portNumber, today = todayIso()) { + return SPONSORS.find(s => active(s, today) && s.ports?.includes(String(portNumber))) || null; +} +export function sponsorForGuide(slug, today = todayIso()) { + return SPONSORS.find(s => active(s, today) && s.guides?.includes(slug)) || null; +} + +// Outbound link with UTM so the clinic can see Border Pulse in its own analytics. +export function sponsorUrl(sponsor, placement) { + const u = new URL(sponsor.url); + u.searchParams.set('utm_source', 'borderpulse'); + u.searchParams.set('utm_medium', 'sponsored'); + u.searchParams.set('utm_campaign', placement); + return u.toString(); +} diff --git a/src/pages/BlogPost.jsx b/src/pages/BlogPost.jsx index acd5405a7..fb268b54d 100644 --- a/src/pages/BlogPost.jsx +++ b/src/pages/BlogPost.jsx @@ -10,6 +10,7 @@ import { updatePageMeta, resetPageMeta } from '@/lib/seo'; import { track } from '@/lib/analytics'; import { blogHreflangs } from '@/lib/hreflang'; import AdsterraBanner from '@/components/ads/AdsterraBanner'; +import { sponsorForGuide } from '@/lib/sponsors'; const STRINGS = { en: { @@ -169,7 +170,7 @@ export default function BlogPost() {
{copyStatus &&

{copyStatus}

} - {!fm.inArticleAd && } + {!fm.inArticleAd && !sponsorForGuide(slug) && }