Skip to content

Latest commit

 

History

173 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mobiera.io

Source for the Mobiera website, served as mobiera.io (Mobiera Norte SA, Panama) and mobiera.com (Mobiera SAS, Colombia): operator-grade software for mobile networks (Aircast, AI One) and verifiable trust on Verana (trust services, integrator certification for Latin America).

Built with Next.js (App Router, standalone output), React 19, Tailwind CSS v4 and TypeScript, on the same stack as 2060.io-website. No database, no accounts. Delivered as a container image (mobiera/website on Docker Hub).

Content

The copy is specified in spec/: one Markdown file per page under spec/pages/, the style rules in spec/STYLE.md, every fact the site may state in spec/facts.yaml. Pages under app/ implement those files; change the spec first, then the page.

News items are Markdown files in content/news/, named YYYY-MM-DD-slug.md with front matter (title, date, tags, summary). They render at /news/<slug> and in the RSS feed at /news/feed.xml.

Design: direction A ("Signal") from spec/design/. Tokens live in app/globals.css; the logo is the existing Mobiera mark and wordmark.

Two domains, two legal entities

The same site answers on two domains, and the domain decides which company of the group the visitor deals with:

Domain Legal entity Registration Address
mobiera.com Mobiera SAS NIT 900662462-4 Cra 13A 86A-42, Bogotá D.C., Colombia
mobiera.io Mobiera Norte SA Registro Mercantil, folio número 812363 World Trade Center 200-B, Suite 214, Calle 53 Este, Marbella, Panama City, Panama

Everything that differs lives in app/lib/entity.ts: name, registration, address, city, data-protection law, canonical origin. Nothing else is duplicated.

  • proxy.ts picks the site from the request (x-mobiera-site, then any forwarded-host header, then Host; a header naming mobiera.com wins) and rewrites to the internal path /<site>/<locale>/.... Pages stay prerendered, once per site and language. Visitors never see the site segment. The response header x-mobiera-site tells which one was served: curl -sI https://mobiera.com/ | grep -i x-mobiera-site.
  • Message files name the entity with tokens, resolved per site when messages load: [[legalName]], [[legalRegistration]], [[legalAddress]], [[legalCity]], [[siteDomain]], [[historyName]], [[dataLaw]], [[rightsDays]], [[noteBogota]], [[notePanama]]. Never write a company name, registration or address in a message file.
  • Server components read the entity with getEntity(locale). Canonical URLs, hreflang, the sitemap, robots.txt, the RSS feed, the structured data, the social image and the contact emails all follow the domain.
  • mobiera.com reaches the app through a reverse proxy. If that proxy hides its name from the app, make it send X-Mobiera-Site: com.
  • Unknown hosts (localhost) get DEFAULT_SITE (io unless set to com).

Languages

English at the bare paths, Latin American Spanish under /es. proxy.ts redirects a first visit whose Accept-Language prefers any Spanish variant to /es; the NEXT_LOCALE cookie set by the language switch wins afterwards. Both languages are prerendered, with hreflang alternates and a sitemap entry each.

  • Copy lives in messages/<locale>/<page>.json, one file per page or shared area, same key tree in both languages. English is the source; a key missing in Spanish falls back to English at build time. Keys are typed from the English files (global.d.ts), so a typo fails tsc.
  • News: content/news/<date>-<name>.es.md beside the English file. Without it the English article is shown on /es with an "English only" note.
  • Contact form and acknowledgement email follow the visitor's language (messages/*/contact.json, messages/*/email.json).
  • The SVG illustrations keep English labels for now.
  • Glossary and register: spec/STYLE.md, section "Spanish (es-419)".

Develop

nvm use            # Node 22
npm install
cp .env.example .env.local   # optional: SMTP for the contact form
npm run dev        # http://localhost:3000

Scripts: npm run build, npm start, npm run typecheck, npm test.

Contact form

/contact posts to app/api/contact/route.ts, which validates the submission (honeypot, time-to-submit, rate limit, consent) and emails it over SMTP with Nodemailer, the same way 2060.io-website does. A submission dropped by the honeypot or the timing check still answers success to the browser, but the pod log says why ([contact] dropped: ...); a delivered inquiry logs [contact] <topic> inquiry emailed. Recipients come from CONTACT_TO with per-topic overrides (CONTACT_TO_CAREERS, ...). Career applications attach the PDF the candidate uploads. With MAIL_HOST unset the form accepts and logs submissions without delivering them.

Configuration

Google mailbox and app password, recipients per topic, GitHub variables and the runtime secret: see docs/configuration.md.

Deploy

GitHub Actions build and push mobiera/website to Docker Hub: dev on every push to main, and main, latest, vX.Y.Z, vX.Y when release-please cuts a release from conventional commits (secrets DOCKER_HUB_LOGIN, DOCKER_HUB_PWD). The "Deploy to Kubernetes (OVH)" workflow rolls any tag out to the OVH cluster's web namespace with the Helm chart in charts/ (nginx ingress, cert-manager TLS), and every release deploys itself. Secrets and the cut-over from GitHub Pages: docs/configuration.md.

Old URLs from the Hugo site redirect (app/lib/redirects.ts); the PHP form handlers and the mock login return 410 (proxy.ts). /images/* keeps the old paths for the mark-only logos and hosted images linked from outside the site.

About

Mobiera Website

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages