Skip to main contentSkip to footer
    Back to Case Studies
    EnpramexGlobal, Houston · Rotterdam · Abu Dhabi
    Corporate WebsiteEmployee PortalVendor Portal

    Enpramex Global

    An integrated energy trading, distribution and logistics company operating in more than 13 countries needed a web presence to match. We delivered a corporate site in 51 languages, an employee portal and a multi-tenant vendor portal, on one brand system.

    Project Preview

    Live website preview - enpramex-global.vercel.app

    37
    Generated pages, plus a language gateway
    51
    Languages, including three right-to-left
    0
    Runtime dependencies in the site build
    3
    Products: public site, employee portal, vendor portal

    One generator, every page

    A single Node script with no dependencies renders all 37 pages from data arrays and a shared shell. Products, regions and offices are entries, not hand-edited files.

    51 languages, no markup churn

    English and Spanish inline; 49 more from flat JSON dictionaries keyed off the English source. Adding a language is one file. Arabic, Urdu and Persian flip the page to RTL.

    Interactive coverage maps

    A per-country world map built from Natural Earth data, rendered as inline SVG, with a region panel and a six-office locations map on the trading-offices page.

    Light and dark, live markets

    A themed design system with a toggle, ambient market-price motion anchored to real quotes, scroll spotlights and a flow-field hero canvas, all paused for reduced motion.

    Employee portal

    Invite-only. News, critical announcements with acknowledgment, a resources library, video training with completion locking, tasks, and an admin CMS with audience targeting enforced in Postgres.

    Vendor portal

    Multi-tenant onboarding, requests and tasks, threaded messaging, append-only document versioning, compliance tracking and an audit trail, with vendor isolation enforced in the database.

    The problem

    Enpramex Global sources, ships, stores, blends and trades energy commodities across more than 13 countries, with a Houston headquarters and offices in Beverly Hills, Mexico City, London, Rotterdam and Abu Dhabi. Its existing site was an unfinished page builder that could not carry the brand, the product catalogue or the distribution story, and it spoke two languages to a company that trades in dozens.

    Behind the public site, two internal audiences had nothing at all: employees spread across six offices with no shared place for announcements, training and tasks, and a growing set of vendors being onboarded over email attachments. The brief became three products on one visual identity: a corporate site that reads as a global company, an employee portal, and a vendor portal where compliance documents live under real access control.

    Constraints we chose

    • No framework for the public site: A corporate site should outlive its dependencies. The generator is Node's standard library and nothing else, and the output is plain files any host can serve.
    • Translate the source, not the markup: Fifty-one languages cannot mean fifty-one copies of every page. Every string keys off its English text, and languages are data.
    • Isolation in the database: For both portals, who can see what is decided by Postgres policies, not by the React code that happens to be running.
    • Claim only what the client claims: Region and office copy restates what the company already publishes. Where real operating detail was missing, the page says less rather than inventing terminal counts or volumes.

    The corporate site

    Thirty-seven pages from one script

    The build script holds the chrome, the bilingual content and the data arrays for offices, products, regions, risk functions, news and navigation. Eight product pages, from naphtha and fuel oil to sustainable aviation fuel and renewable gasoline, are generated from product entries. Eight region pages, the United States, Canada, Mexico, Europe, the Middle East, Africa, South America and Asia Pacific, come from region entries, plus two US retail pages for the branded and unbranded wholesale programmes. Company, trading, risk management, trading offices, transport modes, green approach, media room, careers, contact and the legal set complete the 37, with a separate language gateway.

    Navy design system with Archivo, Inter and Newsreader, light and dark themes, and a green-themed sustainability section
    Cinematic 16:9 hero imagery on photo heroes, media bands and feature cards
    Interactive distribution coverage map, roughly 176 countries as SVG paths, with a side panel that pulls each region's services and link from the same data
    Locations map with twinkle-spark pins for the six offices, and deep links from the topbar, footer and contact page
    Ambient market motion: quote strips and tickers drift around their latest real price, with sparklines and tick flashes
    Organization schema, clean URLs, a mailto contact fallback and an accessibility page

    How 51 languages fit in one codebase

    Every visible string carries its English source as a data attribute, and Spanish inline. For the other 49 languages a client script fetches one flat JSON dictionary per language, once, and swaps text by looking up the English. Precedence is inline attribute, then dictionary, then English fallback. Arabic, Urdu and Persian toggle the document to right-to-left, with dedicated RTL rules in the stylesheet and map labels pinned left-to-right so markers do not slide off their coordinates. An extraction tool rescans the built HTML into a corpus, and a validator reports coverage per language, so the common failure, new copy never back-filled, shows up as a report rather than a mystery.

    The employee portal

    Invite-only by construction

    Admins provision an employee record, an edge function sends the invite, and a database trigger links the accepted auth user to that record. Public signup is disabled; there is no path in.

    One audiences table for everything

    News, resources, videos and tasks are all targeted through a single polymorphic audiences table: everyone, department, job role, location, team or individual. A SECURITY DEFINER matcher inside row-level security decides visibility. The client never filters.

    Training that counts completion

    A progress hook saves position and percent every ten seconds for native video and the YouTube player alike. Completion locks at ninety percent watched, so a required module cannot be ticked off by opening it.

    Publishing as a trigger, scheduling as a cron

    Publishing stamps the timestamp and fans out notifications and task assignments exactly once. A pg_cron job promotes scheduled posts every five minutes and sends due-soon reminders. One dashboard function returns a ranked feed: critical unacknowledged, overdue tasks, required training, due soon, then news.

    The vendor portal

    The vendor portal is the sibling of the employee portal, same stack and design system, its own isolated backend, and a harder problem: many organizations that must never see each other, sharing one auth pool with Enpramex staff.

    Two trust domains, one auth pool

    Staff roles live in one table; vendor roles live on the vendor-user record. A vendor account has zero rows in the staff table and no write path to it, and belongs to at most one vendor organization, ever. Every vendor-scoped row is stamped with its tenant id by a trigger, and every policy composes from the current tenant plus status-tier predicates.

    A state machine in the database

    Prospective, pending onboarding, under review, active, plus on hold, suspended, inactive and terminated. The legal transition graph is enforced by a trigger, even for admins. Onboarding progress is derived by a function, never stored, and the only vendor-initiated transition is a precondition-checked submit-for-review call.

    Documents that cannot be edited

    Vendors never modify a document; a new upload supersedes the old row in a version chain, with versions assigned under a row lock and every prior version kept for audit. Staff review flips a version to approved or rejected, which also settles the linked request and compliance requirement.

    Announcements and audit

    Announcements target all vendors, a category, one vendor or one user through the same audiences pattern, matched server-side so vendors never read the targeting rows. The activity log is written only by database triggers, with cascade noise and no-op writes suppressed, and every row carries the tenant id so a per-vendor timeline is one indexed query.

    Problems worth talking about

    Russia across the dateline

    Countries whose land crosses the antimeridian decode with a spurious edge stitched across the whole map. The map generator splits any ring at a jump wider than half the map before simplifying, so the real coastline reconnects and the stray sliver drops out on its own.

    Eighteen keys or six

    Composing office addresses as baked strings would have added eighteen new phrases to translate into 49 languages. Emitting the same leaf spans the office cards use meant six genuinely new phrases and every existing country name reused.

    Glass without seams

    The frosted-glass maps showed dark specks wherever simplified country paths left hairline gaps. Each path now strokes in its own fill colour, invisible by construction, and translucency lives on the group rather than per path so strokes cannot double-composite into seams.

    Failing closed on suspension

    Rather than checking a status flag in every policy, suspending an organization nulls the tenant context itself. Every row policy and every storage rule then denies in the same instant, with nothing to forget.

    Where it stands

    Reported honestly

    The corporate site is live and public. The employee and vendor portals are built, tested and deployable, with their production rollouts gated on the client's SMTP and domain configuration. The numbers here are counts from the repositories: pages, languages, dependencies, products. We do not publish traffic, employee or vendor counts for a client platform, and the region copy on the site deliberately claims no volumes the company has not published itself.

    Adding a language never touches page markup. You only add a JSON file.

    Enpramex Global engineering notes

    What This Project Does Well

    The public site has no framework and no build-time dependencies: static HTML, CSS and vanilla JavaScript, generated by one Node ESM script and deployed on Vercel
    Offices, products and regions are single sources of truth; the six-office address renders in three places from one array, and the i18n system reuses translated leaf strings instead of adding composite keys
    A translation coverage validator runs over the corpus so a missing key falls back to English visibly rather than breaking the switcher
    Both portals share one design system and stack but live in fully isolated Supabase projects
    Employee content visibility is decided by a SECURITY DEFINER matcher in row-level security, never by client filtering
    Vendor lifecycle transitions are validated by a database trigger even for admins; onboarding progress is derived by a function, never stored
    Suspending a vendor organization nulls its tenant context for every user, so every policy and storage rule fails closed at once
    No public storage buckets anywhere: every document is served through a signed URL

    Technologies Used

    Corporate site: static HTML, CSS and vanilla JavaScript generated by a zero-dependency Node ESM build, inline SVG maps from Natural Earth data, JSON i18n dictionaries, Vercel. Portals: Vite, React 19, TypeScript strict, Tailwind CSS 4, shadcn/ui, TanStack Query, React Router 7, Supabase (Postgres, Auth, Storage, row-level security, Edge Functions, pg_cron), Playwright, Vercel

    Ready to Build Something Similar?

    Let's discuss how we can help transform your business with a custom digital solution.