The footer every published viz should have: who made it, where to find them, and (when the viz is a rebuild or a remix) who made the original.
Adapted from Devi Ramanathan · original viz
ES Eric Summers [in] [X] [ig] [tp] [@]
Tableau consultant, Denver
Data: Sample Superstore
It is the one kit extension that reads no data at all. Everything comes from Configure, which is what lets it run in two different hosts (see below).
#What it is
- Your credit, name, an optional role or tagline, an optional profile link that makes the name itself clickable, and an optional round initials chip.
- A row of link icons, LinkedIn, X, Instagram, Tableau Public, GitHub, YouTube, Bluesky, website, email. Fill in the ones you use; an empty field renders no icon, so the row is exactly as long as you want it.
- Attribution, only when there is any, the original author's name, their profile, and the original viz, with a lead-in you choose ("Original by", "Adapted from", "Inspired by"). Leave those fields blank and the card is just your credit and your links. That is the default.
- Small print, a data source, a license, a "last updated", whatever the footer owes the reader.
- Fits the zone. A footer is whatever height you dragged it to. The card measures its own content, scales to fill the height, and stacks onto two or three lines only when there is room for them. If the row is still crushed it sheds in a fixed order: small print, then the role, then the lead-in, then the attribution, then the chip. The icons and your name are the last things standing, and it never scrolls.
- Five themes (light, paper, slate, dark, and clear, which draws no background so it sits on the dashboard's own color), a pickable accent, four alignments, three icon styles, three sizes, and an optional hairline rule.
- Configure live-previews every change as you make it; Save persists to the workbook.
#Two hosts, one page
As a dashboard extension. Drop it on the dashboard, Configure it, done. The settings live in the workbook. Desktop, Server, Cloud.
As a Web Page object. Tableau Public does not run network-hosted extensions
at all, so on a Public viz a .trex is not an option. The same page therefore
also reads its whole configuration off the query string, which means a Web
Page object pointed at it gives you the identical footer, links live and
clickable, on Tableau Public.
The Configure dialog's Tableau Public tab builds that URL for you and copies it. Two forms:
…/index.html?by=Eric+Summers&role=Tableau+consultant&li=linkedin.com/in/me&x=x.com/me
…/index.html?cfg=<base64url of the settings JSON>
Readable spells each setting out (short aliases; the full key names work too). Packed folds them into one value, which survives a long config better in Tableau's URL field. Both are read at load; there is no Tableau host involved.
The page paints from the URL first and only then waits on initializeAsync, so
it never shows an empty frame in either host and never hangs in the one where
that promise does not resolve.
#URL keys
| Alias | Setting | Alias | Setting |
|---|---|---|---|
by |
your name | orig |
original author |
role |
role / tagline | origurl |
original author profile |
me |
your profile link | vizurl |
original viz link |
note |
small print | vizlabel |
text for the viz link |
li x ig tp |
LinkedIn, X, Instagram, Tableau Public | pre |
lead-in ("Original by") |
gh yt bs |
GitHub, YouTube, Bluesky | theme accent align size |
look |
web mail |
website, email | icons rule mark sep |
icon style, rule, chip, separator |
Only http/https destinations render. A bare linkedin.com/in/me is completed
to https://; anything with another scheme is dropped rather than linked.
#Run it locally
From the repo root:
python scripts/kitserve.py
Then in Tableau, drag an Extension object onto a dashboard → Access Local
Extensions → manifest.local.trex, then Configure.
Use that server rather than python -m http.server. Two things it handles that
a plain static server does not, and both surface inside Tableau as a blank or
errored zone rather than as an error you can read: it answers on IPv4 and
IPv6 (a machine that resolves localhost to ::1 first will otherwise get a
refused connection), and it resolves ./lib/ to kit/_shared/lib, which only
exists in a provisioned copy and is missing from the repo folder.
(For the Web Page object route the Extensions API is not needed at all, so a
configured URL renders fine without lib/. The "Couldn't start" message only
appears when there is nothing configured and nothing loaded.)
#Get it
Attribution Card ships in the Extension Kit ($59). See it live on the demo gallery.