ShapeKit
← Back to Blog

Agency Client Portal Customization Sinkholes

How client portals turn into per-client maintenance nightmares — and the constrained shaping model that gets you out.

By ShapeKit Team

If you've built software for agencies, you know the shape of the problem before I describe it.

You scope a client portal. One dashboard, showing the client's campaign data, account health, whatever they hired the agency for. You build it. It looks good. You ship it.

Then Client A calls. "Can you add a column for contract value?" You add it.

Then Client B calls. "We don't want contract value — can you hide that and show spend by channel instead?" You branch the logic.

Then Client C wants the view that Client A has, but with Client B's sorting, and two columns no one else has asked for yet.

Eighteen months later, you're maintaining seven dashboard variants for a feature that was supposed to be one.

The structural problem with "one dashboard per client"

Most agencies don't set out to build N dashboards. They build one, then respond to client requests the only way they can: by writing code.

The pattern looks like:

  1. Build the default dashboard
  2. Client requests a customization
  3. Developer adds a flag, a column, a filter
  4. Repeat until the codebase is a maze of per-client conditionals

This is survivable at 5 clients. At 15 clients, it's a maintenance crisis. At 30, it's a liability — any change to the underlying data model risks breaking customizations you've forgotten existed.

The problem isn't that clients have different needs. They do, and they're right to. The problem is that there's no mechanism for clients to configure their own view. Every change requires a developer.

Why building a client-configurable layer is harder than it looks

The obvious fix is to let clients configure their own dashboard. Build a settings panel, store preferences, call it done.

Agencies that try this run into the same walls that product teams hit:

Shared data model, divergent views. Your data model is built for the underlying data, not for each client's preferred way of slicing it. Client A wants to pivot on region. Client B wants to pivot on channel. Neither pivot is how the data is natively structured. Surface-level configuration doesn't solve this — it just pushes the complexity to query time.

Who controls what. The agency usually wants some columns to be fixed — mandatory metrics that are in every client report. Other columns should be available but optional. Some clients should be able to reorder; others shouldn't. Implementing "admin controls the bounds, client customizes within them" requires an authorization model layered on top of your configuration model.

White-label branding adds another dimension. If each client has a branded portal, now you're managing configuration plus branding per client. The matrix grows fast.

Support when something looks wrong. When a client calls because their dashboard "looks wrong," the first thing you need to know is what they've configured. If the customization state is scattered across flags and overrides in your codebase, that diagnosis takes an hour.

The third option: constrained shaping

Teams that escape the N-dashboard trap don't do it by building a better settings modal. They do it by changing the mental model.

The key insight: you don't need to let clients configure anything. You need to let them configure the things that are safe to configure, within bounds you define.

This is the constrained shaping model:

  • You (the agency developer) define which columns are fixed, which are optional, which can be reordered
  • The client shapes their view within those bounds — adding optional columns, hiding what they don't use, setting their preferred sort
  • You can set agency-wide defaults that any client can adjust
  • You can lock certain views for certain clients entirely

The result: one codebase, one dashboard definition, N client views. When you change the underlying data model, you update the shape definition. The client customizations inherit the change automatically.

What this looks like in practice

Imagine you're an agency managing 20 clients with different levels of access. Your dashboard has:

  • Fixed columns: client name, total spend, primary KPI (mandatory for all clients)
  • Optional columns: spend by channel, region, campaign type, contract value (available but not default)
  • Sortable on: any visible column
  • Max visible columns: 10

Agency admin sets this definition once. Each client opens their portal and sees the fixed columns plus whatever optional columns they've chosen to surface. No two clients see the same dashboard. Nobody called your developer.

When a new client signs on, they start with the default view and adjust from there. When you add a new optional column to the definition, every client immediately has access to it — none of their existing customizations break.

This is what ShapeKit is built to enable. You define the shape. Your clients shape their view within it.

ShapeKit launches April 15 — full product, no waitlist. Sign up for early access.


Next post: "Build 80%, let your users shape the last 20%" — publishing March 31.