LinkedIn plugin — how the types work

The LinkedIn plugin turns a LinkedIn data-export archive into a live, browsable profile. Every type is a dynamic node type — its C# lives under Source/*.cs and the mesh compiles it live on install. No app rebuild, no NuGet.

The profile

LinkedIn/LinkedInProfile is the hub. Its content (LinkedInProfile) carries display name, headline, about, picture/profile URLs and page stats (followers, impressions, likes…). Its Overview view composes a rich page: header + stats table, then Experience, Education (pulled live from the profile's child nodes — nodeType:LinkedIn/Position / LinkedIn/Education) and Skills, which come from the archive CSV via LinkedInSkill rather than from child nodes.

The archive data types

The rest are one type per LinkedIn archive CSV. Each is the same shape — a content record + a CSV Loader (reads archive/<File>.csv from the partition's content collection) + a Data view that renders a sortable DataGrid:

Type Archive CSV Grid
Position Positions.csv title · company · location · dates
Education Education.csv degree · school · dates
Skill / LinkedInSkill (profile) / Skills CSV skill names
Connections Connections.csv name · company · position · connected-on
Message Messages.csv from · to · date · subject · content
Invitation Invitations.csv from · to · direction · sent-at
EndorsementGiven / EndorsementReceived Endorsement_*_Info.csv skill · person · date · status
RecommendationGiven Recommendations_Given.csv name · company · title · text
CompanyFollow Company Follows.csv organization · followed-on
Learning Learning.csv title · type · watched · completed
RichMedia Rich_Media.csv date · description · link

Every view is a template — data binds, never bakes

Each Data grid (and the Post Feed, and the TileMigration status page) is a TEMPLATE, per the platform's Templates first, data later rule: the area returns its whole control tree at once — the heading and the grid bound by pointer to /data/{slot} — and the type's own workspace stream, subscribed when the tree is built into the area, writes the rows into those slots. The page therefore exists before the rows do: the grid draws its loading shape, the heading gains its count when the rows arrive, and a re-import reaches an open page without a re-render.

The shape lives once, in the partition-level shared source LinkedIn/Source/LinkedInFedView.cs (GridPage, Feed); every type that renders through it lists shared=@LinkedIn/Source in its sources — including LinkedInProfile, which compiles LinkedInSkill/Source. Each Tests area pins its view with LinkedInFedView.AssertGridTemplate (or EveryViewIsStatic): given rows that never arrive, every view is still a control, bound to its slot — a deferred WithView((h, c) => stream) fails it.

Loading your own archive

  1. Request your data export from LinkedIn (Settings → Data privacy → Get a copy of your data).
  2. Drop the CSVs into the partition's content/archive/ collection.
  3. The types' loaders pick them up — no code changes; each grid fills from its CSV.