Icons & Display
Customise how your portal endpoints look — icon types, scrollable containers, ordering, and visibility toggles. Because an endpoint without an icon is just a sad text link.
Every endpoint you create gets a slot in FluentCart's Customer Portal sidebar. That slot needs an icon, a position, and possibly some display manners. This page covers all the visual knobs you can turn — from SVG code to viewport-aware scroll containers — so your portal doesn't look like a government intranet from 2003.
Icon Types
Each endpoint supports three icon formats. Pick whichever suits your aesthetic sensibility (or lack thereof). The icon type is selected via a dropdown in the endpoint editor, and a live preview renders below the field so you can see what you're inflicting on your customers before you save.
Paste raw SVG markup into the textarea field. The SVG is rendered inline in the portal sidebar, which means it scales perfectly at any size and supports currentColor for theme-aware colouring. If FluentCart switches between light and dark mode, your icon follows along without you lifting a finger.
A live preview appears below the textarea as you type — useful for catching that moment when your hand-crafted SVG turns out to be an invisible 0x0 rectangle.
Example:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round">
<circle cx="12" cy="12" r="10"/>
<path d="M12 6v6l4 2"/>
</svg>Security sanitisation:
Because allowing arbitrary SVG in your admin panel would be a spectacular idea, the plugin strips the following on save:
| Stripped Element / Attribute | Why |
|---|---|
<script> tags | Obviously |
Event handlers (onclick, onload, onerror, etc.) | XSS vectors |
xlink:href attributes | Can reference external resources |
javascript: protocol in href values | Another XSS classic |
<foreignObject> elements | Can embed arbitrary HTML inside SVG |
What survives sanitisation is a clean, inert SVG that renders as a visual element and nothing more. If your SVG relies on JavaScript to function, it will not function. That's the point.
Use currentColor
Design your SVGs with stroke="currentColor" or fill="currentColor" so they inherit the sidebar's text colour. This ensures proper contrast in both light and dark mode without you maintaining two icon sets like some kind of design masochist.
Scrollable Container
Long content inside a portal endpoint can push the sidebar navigation off the bottom of the screen, turning your carefully crafted portal into an infinite scroll nightmare. The scrollable container option wraps your endpoint content in a height-constrained box with its own scrollbar, keeping the portal layout intact.
All content types except Redirect support this option. Redirects don't render content — they send the user elsewhere — so the scrollable container toggle is hidden when you select Redirect as the content source.
The container automatically fills the remaining viewport height, minus a 24px bottom margin for breathing room. No magic numbers to guess, no CSS to write — it measures the container's offset from the top of the viewport and sets max-height dynamically.
How it works:
max-height = window.innerHeight - element.getBoundingClientRect().top - 24pxThe minimum height is clamped at 200px, so even on absurdly small viewports the content area doesn't collapse into a unusable sliver.
Recalculation triggers:
- Window resize events
- DOM mutations (content loaded asynchronously, AJAX updates, etc.)
This mode is ideal when you don't know how tall the content will be — which, let's be honest, is most of the time. The content scrolls within the portal frame, and the page itself stays put. Your sidebar navigation remains visible. Order is maintained. Everyone's happy.
When to Skip It
Not every endpoint needs a scrollable container. If the content is short — a brief info panel, a couple of links, a haiku about your return policy — just leave scrollable container disabled. The content will render at its natural height within the portal layout. No scrollbar, no wrapper, no unnecessary complexity.
Endpoint Ordering
Two separate things decide where an endpoint lands: its order relative to your other endpoints, and its position among FluentCart's built-in items.
Relative to your other endpoints
The endpoint list has up/down arrow buttons. Click to reposition. Changes save immediately via the REST API, so there's no separate "save order" button to forget about.
Relative to FluentCart's own menu
Each endpoint has a Menu Placement setting in the editor, under Status. Pick the built-in item you want to sit next to:
| Choice | Result |
|---|---|
| First — above Dashboard | Top of the menu |
| After Dashboard | Second, directly under Dashboard |
| After Purchase History, After Subscription Plans, After Licenses, After Downloads | Directly under that item |
| Before Profile | The default, and where every endpoint used to land |
| After Profile | Bottom of the menu |
Existing endpoints keep Before Profile, so upgrading changes nothing until you say otherwise.
The catch worth knowing before you plan a layout: FluentCart's menu is not the same for every visitor. It hides Licenses when FluentCart Pro or the license module is off, and hides Subscription Plans from customers who don't have any. So "second from the top" is a different neighbour for different people.
That is why placement is anchored to a named item rather than to a number. When the item you picked isn't on screen, the endpoint takes the same slot next to the nearest item that is — "After Licenses" on a site without licenses lands where Licenses would have been, not at the bottom of the menu.
Endpoints sharing a slot keep the relative order you gave them in the list, and menu items belonging to other plugins are never moved or dropped.
Active / Inactive Toggle
Each endpoint has a status toggle in the endpoint list. This is a binary state — active or inactive — and it does exactly what you'd expect:
| Status | Behaviour |
|---|---|
| Active | The endpoint is registered with FluentCart on page load and appears in the Customer Portal sidebar. Customers can see and navigate to it. |
| Inactive | The endpoint is saved in the database but not registered with FluentCart. It does not appear in the portal sidebar. Invisible. Dormant. Waiting. |
This is useful for drafting endpoints before publishing them. Build out a new portal page, preview it in the admin, and only flip it to active when you're satisfied. Or deactivate an endpoint temporarily without losing its configuration — because deleting things you might need later is a rookie move.
Quick Reference
| Feature | SVG Code | Dashicon | Image URL |
|---|---|---|---|
| Scalability | Vector, infinite | Font-based, scales well | Depends on source image |
| Theme-aware colour | Yes (currentColor) | Inherits WordPress styling | No (static image) |
| Dark mode support | Automatic via currentColor | Automatic via font colour | Manual (use a transparent PNG) |
| Extra assets loaded | None (inline) | None (built-in font) | HTTP request per icon |
| Customisability | Full — any SVG you want | Limited to 29 curated icons | Full — any image you want |
| Setup effort | Medium (need SVG markup) | Low (pick from dropdown) | Low (paste a URL) |
| Mode | Height Calculation | Technology | Best For |
|---|---|---|---|
| Auto-fit Viewport | viewport - offset - 24px (min 200px) | JavaScript + resize/mutation observers | Dynamic content, unknown heights |
| Fixed Height | User-defined (200-2000px, default 600px) | Pure CSS max-height | Known content dimensions |
| Disabled | Natural content height | None | Short content that fits naturally |
Content Sources
The six content source types for portal endpoints — WordPress Pages, Shortcodes, HTML, iframes, Redirects, and Custom Post Types. How each one renders and when to use it.
Troubleshooting
Common issues with FCHub Portal Extender and how to fix them — because something always goes sideways.