Minhas Extensões
Todas as extensões
Produtividadev0.19.1Auto-hospedadaCódigo privado

LinkedIn Enhancer

by José DA COSTA

Ferramentas de produtividade que melhoram o LinkedIn.

O LinkedIn Enhancer acrescenta ferramentas práticas dentro do próprio LinkedIn: impede que o feed se recarregue ao mudar de separador, impede a reprodução automática de vídeos, oculta anúncios e ruído do feed (publicações patrocinadas, sugestões, recomendações, cartões de mudança de emprego, módulo LinkedIn Notícias), copia qualquer publicação e toda a sua árvore de comentários como um prompt pronto para IA, pode arquivar tudo o que percorre numa base de dados local no seu dispositivo, adiciona um botão « Não tenho interesse » num clique. Cada ferramenta é um simples botão de ligar/desligar, nada é enviado para a Internet, e todas as definições ficam no seu navegador.

  • Mantenha a posição de leitura e o rascunho ao mudar de separador
  • Pare a reprodução automática dos vídeos do feed ao percorrer
  • Um clique transforma a publicação, o seu link e os comentários num prompt de IA
  • Arquive tudo o que percorre numa base de dados local e privada
  • Oculte anúncios, sugestões, recomendações, mudanças de emprego, promoções de emprego & Learning e Notícias
  • Um botão « Não tenho interesse » para afinar o feed em privado, num clique
  • Nenhum dado sai do navegador; cada ferramenta liga-se de forma independente

Disponível para

chromechromefirefoxfirefoxedgeedgebravebraveoperaopera
Última versão
v0.19.1
5 de junho de 2026

Porque ajuda

O LinkedIn recarrega o feed assim que muda de separador, apagando a sua posição de leitura e o comentário que estava a escrever. Os vídeos começam sozinhos, enquanto publicações patrocinadas, ofertas Premium, publicações sugeridas, cartões de « pessoas a seguir », anúncios de mudança de emprego e o módulo de Notícias empurram as atualizações reais para fora do ecrã. E quando uma publicação gera uma boa discussão, não há forma limpa de extrair o texto para o analisar. Esta extensão elimina essa fricção no momento — de forma privada, com tudo a ficar no seu dispositivo.

Funcionalidades

Parar a atualização automática do feed

Mantém a sua posição de rolagem e o rascunho de comentário ao mudar de separador e voltar.

Parar a reprodução automática de vídeos

Os vídeos do feed deixam de começar sozinhos ao percorrer; só são reproduzidos ao clicar.

Copiar uma publicação como prompt pronto para um LLM

Um clique copia uma publicação, o seu link real e toda a sua árvore de comentários, formatado para um LLM. O texto do prompt é totalmente personalizável.

Arquivar as publicações que percorre

Regista, opcionalmente, cada publicação vista numa base de dados local no seu dispositivo, que pode pré-visualizar e exportar em JSON, CSV ou XLS. Nada sai do navegador.

Ocultar anúncios e publicações patrocinadas

Substitui o conteúdo patrocinado e promovido, bem como as ofertas Premium do próprio LinkedIn, por um pequeno espaço reservado.

Ocultar publicações sugeridas

Substitui os cartões « Sugestões » do feed por um espaço reservado (desativado por predefinição).

Ocultar recomendações de perfil

Remove os cartões « Recomendado para si » (pessoas a seguir) do feed.

Ocultar mudanças de emprego

Remove do feed os cartões de ocasião « começou uma nova posição ».

Ocultar o LinkedIn Notícias

Remove o módulo « LinkedIn Notícias » da coluna da direita e as suas notícias em destaque.

« Não tenho interesse » num clique

Adiciona um botão « Não tenho interesse » ao lado de « Gosto » que diz de forma privada ao LinkedIn para mostrar menos conteúdo deste tipo — ninguém é notificado.

Notificações de atualização

Avisa-o quando uma nova versão é publicada para a transferir e instalar.

Permissões

storageactiveTabalarmsnotificationsclipboardReadunlimitedStoragehost: *.linkedin.com

Histórico de versões

Publicado em 5 de junho de 2026

Fixed

  • "Hide LinkedIn Learning promos" now catches every card. Some LinkedIn Learning promo headers render the brand with a non-breaking space ("LinkedIn Learning"), which slipped past the regular-space matcher and left those cards visible. The feed-clutter scan now normalizes non-breaking spaces before matching, so all variants of the promo are hidden as intended.
Publicado em 3 de junho de 2026

Removed

  • The "Show relationship status" tool is gone. The small per-post badge that showed the author's connection degree (1st/2nd/3rd) and whether you follow them — and its showRelationshipStatus setting, the popup/options toggles, the relationship-status module and its i18n strings — have all been removed.
Publicado em 3 de junho de 2026

Added

  • Hide LinkedIn Learning course promos. A new opt-out toggle (on by default) replaces the in-feed LinkedIn Learning promo cards ("Cours populaire sur LinkedIn Learning" / "Popular course on LinkedIn Learning") with a small placeholder — same mechanism as the other clutter hiders. Matched by a short feed header that carries the "LinkedIn Learning" brand (the bare logo label is ignored), so it works across the various course-card titles and locales.
Publicado em 1 de junho de 2026

Added

  • Hide LinkedIn's in-feed job-search promos. A new opt-out toggle replaces the "Trouvez des postes à pourvoir" / "Find jobs for you" promo cards LinkedIn injects into the feed with a small placeholder — same mechanism as the other clutter hiders (multilingual, reversible, counted toward the toolbar badge).
Publicado em 1 de junho de 2026

Added

  • The toolbar icon shows the extension is inactive off LinkedIn. On any non-LinkedIn tab the icon is now grayed out (faded), and clicking it shows a short reassuring notice — "You need to be on LinkedIn — this extension only works on LinkedIn…", with an "Open LinkedIn" button — instead of the settings panel. On LinkedIn the icon is colored and the popup shows the tools as before. This makes it obvious the extension does nothing on other sites. (Graying degrades gracefully where the canvas API is unavailable; the popup notice always shows.)
Publicado em 1 de junho de 2026

Fixed

  • Brave is now listed and downloadable on the showcase page. Brave is Chromium and runs the Chrome build verbatim, but the public listing showed it as unsupported and offered no Brave download. The release now also publishes a Brave-labeled zip (a copy of the Chrome build, via pnpm zip:brave) and the showcase lists Brave among the supported browsers (Chrome, Firefox, Edge, Brave, Opera).
Publicado em 1 de junho de 2026

Changed

  • "Not interested" tooltip now warns about irreversibility and appears instantly. The button's tooltip shows immediately on hover/focus (a custom instant tooltip instead of the delayed native one) and now leads with the warning that the click cannot be undone and durably changes LinkedIn's algorithm — so it should only be used on content you are 100% sure you do not want.
Publicado em 1 de junho de 2026

Changed

  • Update notifications are gentler and dev-mode aware. The daily "new version available" check now runs only on manual installs (store-managed installs auto-update, so they are skipped via management.getSelf() — no extra permission), fetches the version at most once a day no matter how often the MV3 service worker restarts, and reminds at most once a day. Once you click the notification (acknowledging it), it never nags again for that version — only a newer release re-prompts.
Publicado em 1 de junho de 2026

Changed

  • The showcase page now updates automatically on every release. This repo is the source of truth for the public listing content (store/extension.json, in English/French/Portuguese); the release workflow regenerates extension.json — with the permissions derived from the built manifest — and pushes it to the releases repo, which revalidates the site. The listing's features, permissions and descriptions can no longer drift from what ships (the previous page still showed the removed sidePanel permission and a stale feature list).
Publicado em 1 de junho de 2026

Removed

  • The side panel is gone. It only duplicated the toggles already in the popup and the options page, on the same storage — no feature of its own. Removing it drops the sidePanel permission and the side_panel manifest entry, deletes the src/entrypoints/sidepanel/ surface, and leaves two consistent UI surfaces (popup + options) across every browser.
Publicado em 1 de junho de 2026

Changed

  • Clearer "Not interested" tooltip. It now says the action is completely private and that no one (not just the author) is notified — contrasted with a Like, which appears on your profile.
Publicado em 1 de junho de 2026

Added

  • "Not interested" button in the post action bar. A new opt-out button sits next to "Like" and, on click, drives LinkedIn's own "..." menu → "Not interested" — same effect as doing it by hand (the post leaves your feed and future recommendations are tuned away from this topic/author; private, the author is not notified). It reuses LinkedIn's thumbs-down icon and, unlike a public Like, can be used freely and repeatedly. All the menu-driving happens only on click — injecting the button does no identifier lookup, so it does not slow the feed. A hover tooltip summarizes what the feature does.
Publicado em 1 de junho de 2026

Added

  • Hide LinkedIn News. A new opt-out toggle removes LinkedIn's "News" modules (the right-rail "LinkedIn Actualités" card with trending stories). The module is identified with certainty by its exact localized heading plus a card holding several story links, then hidden in place; the climb stops before the rail footer so the About/copyright links are never removed.

Changed

  • Suggested posts are no longer hidden by default. The "hide suggested posts" toggle now starts OFF (existing users keep their current setting).

Fixed

  • The copy prompt's default URL header now carries the {{url}} variable. The resolved post link lands inside that line via the variable instead of being appended separately — no duplicate when the header has {{url}}, the raw URL is still appended for a custom header without it, and a {{url}} placed elsewhere skips the header. Reset the prompt to pick up the new default.
Publicado em 31 de maio de 2026

Fixed

  • Comment scraping retries LinkedIn's "couldn't load comments" error. When the thread comes back as "Impossible de charger les commentaires" (and its localized variants), the Copy button and the comment archive now click "Try again" — up to a few times — instead of capturing an empty thread.
  • Line breaks in a post's text are now preserved everywhere. Extraction keeps the real \n characters LinkedIn uses and also converts <br> elements to newlines, so the copied prompt and the archived record match the post's paragraph structure. The archive preview renders that structure too (it was collapsing every line break onto one line).

Added

  • Hide "job change" posts. A new opt-out toggle replaces LinkedIn's job-change occasion cards ("Changement de poste de <name>" / "<name> started a new position") with a small placeholder, the same way the sponsored/suggestion/ recommendation hiders work. Multilingual, reversible, and counted toward the toolbar badge.
  • {{url}} variable for the copy prompt. When "Include post URL" is on, the resolved post link is now available as a {{url}} placeholder you can drop into any prompt field (intro, instructions, headers) — the options show the token in grey next to that checkbox. When you place {{url}} yourself, the link is no longer also appended at the end (no duplicate); leave it out and the trailing URL line behaves exactly as before.
Publicado em 30 de maio de 2026

Fixed

  • Post archive captured the wrong author, text and comment count on some posts. Verified live on the feed, three extraction bugs surfaced and are fixed: (1) the author was taken from the social-proof header ("X aime ce contenu") whose profile link precedes the real author's — it now reads the real author from the post's control/hide button aria-label; (2) the caption occasionally captured LinkedIn's screen-reader "Feed post" heading instead of the real text, now stripped; (3) the comment/reaction/repost counters could capture a blank from a number-less label, now requiring an actual digit. The author's headline also no longer includes the mashed name + connection-degree prefix. Covered by new regression tests.
Publicado em 30 de maio de 2026

Added

  • Post archive — save everything you scroll past. A new opt-out tool records every post that enters the viewport into a local chrome.storage.local database that never leaves the device, building over time a record of everything seen in the feed. Each capture keeps all the useful information the render exposes (or hides): author and their headline/title, the post text, reaction count and the reaction types present, comment and repost counts, and how long ago it was posted. Posts are classified as classic, suggestion or sponsored, and three checkboxes pick which types to archive (the suggestion/sponsored boxes are greyed out when the matching "hide" tool is on, since hidden posts are never rendered to capture). Each post is deduped by a content hash so scrolling up and down stores it once. The options page shows the live count, an inline preview of the stored rows, and lets you reset the database or export it as JSON, CSV or XLS. Two heavy opt-in options (default off) additionally capture the real post link (via the "…" menu, like the Copy button) and the full comment thread (by expanding it, like the Copy button). The popup also exposes the archive toggle. The options and update sections spell out that the archive is local-only and which repository URL the update check fetches. Adds the unlimitedStorage permission so the archive can grow large.
  • Copy-button prompt is fully localized, with injectable variables. The prompt strings the Copy button assembles are now translated end to end — French when the UI is French, English when it is English — instead of being hard-coded English with a single inline language word. They also support variable placeholders ({{language}}, {{locale}}, {{date}}, {{datetime}}) that are substituted at copy time, so the same template adapts to the active display language and the current date.

Changed

  • The Copy button now copies the REAL post link. Modern LinkedIn exposes the post's permalink nowhere in the DOM (no URN attribute, no anchor), so the copy prompt used to fall back to the bogus https://www.linkedin.com/feed/ page URL. It now drives LinkedIn's own flow — opens the post's "…" menu and clicks "Copy link to post" (multilingual), which makes LinkedIn write the canonical URL to the clipboard, then reads it back. When no real link can be resolved, the URL line is omitted entirely (never the /feed/ placeholder). Adds the clipboardRead permission for the read-back.

Fixed

  • The Copy button's icon now always shows (and matches LinkedIn's weight). The icon was built by cloning the native Comment button and only set if (svg !== null); when LinkedIn had not lazily rendered that icon yet at clone time, the copy button captured an empty placeholder and stayed icon-less (it appeared only "sometimes"). We now build our own <svg> deterministically, replace whatever sits in the icon slot, and repair any icon-less button on the next pass. The glyph is LinkedIn's own solid document-copy icon (extracted from their icon bundle into jose/icons/), so it no longer looks thin next to the native Like/Comment/Repost/Send icons.
Publicado em 30 de maio de 2026

Added

  • Stop videos from autoplaying. A new opt-out toggle blocks LinkedIn's feed videos from starting on their own. LinkedIn auto-plays the video nearest the viewport through an IntersectionObserver calling Video.js player.play() (there is no hover handler — the "it starts when I mouse over it" impression comes from scrolling it into view). A MAIN-world content script (linkedin-stop-video-autoplay) overrides HTMLMediaElement.prototype.play to refuse any start that is not preceded by a genuine user gesture (event.isTrusted), so a real click still plays the video while the automatic start on scroll is blocked. Full analysis in jose/blog/2026-05-30-linkedin-bloquer-lecture-automatique-videos-feed.md.

Fixed

  • Graceful handling of an invalidated extension context. When the extension is reloaded or updated (a dev-mode HMR rebuild, or a production auto-update) while a LinkedIn tab stays open, the already-injected content script kept running with a severed browser.runtime handle — turning into a "zombie" that spammed thousands of chrome-extension://invalid/ requests while the tools (Copy button, clutter hiding, counters) silently stopped working. The content script now detects the revoked context (via @lib/context-guard), tears down its DOM watcher, and shows a one-click "Reload" notice instead of lingering broken until a manual reload. It also swallows the one-shot "Extension context invalidated" error (and its async rejection) in its own world, and bails out quietly if it is (re)injected onto an already-dead context, so the transition no longer surfaces as an uncaught content-script error.

Changed

  • Feed-clutter hiding now does one combined DOM scan instead of three. applyFeedClutter used to run the label-matching loop once per category (sponsored, suggestions, recommended), re-scanning the whole document and re-allocating every element's textContent three times on every watcher tick. It now scans span, p, h2, div a single time and tests the three matchers together (behavior identical — a label matches at most one category), roughly halving the per-tick CPU and GC pressure on large feeds.
  • Documented the feed's migration to React Server Components. The desktop feed now flows through flagship-web/rsc-action / SDUI ids (e.g. com.linkedin.sdui.pagers.feed.mainFeed), and the refresh is the SDUI action proto.sdui.actions.core.RefreshScreen, not the legacy Voyager voyagerFeedDashMainFeed query. The stop-feed-refresh module doc was rewritten to reflect this: the version-agnostic Page Visibility override is the primary defense (verified effective), the Voyager fetch-block is kept only as a legacy fallback, and the rare server-pushed RefreshScreen is documented as a known, not-yet-intercepted residual.
  • Simplified the extension name and description. The title shown in chrome://extensions is now just "LinkedIn Enhancer" (dropped the "by José DA COSTA" suffix), and the description drops the "Built with WXT, React, and TypeScript" tail, in both the en and fr locales.
Publicado em 30 de maio de 2026

Added

  • Per-category hidden counters in the popup and side panel. Each of the four "hide" toggles (sponsored posts, LinkedIn ads, post suggestions, profile recommendations) now shows a count pill of how many items it has removed on the active tab, breaking down the single total already painted on the toolbar icon. The counts are cumulative: because LinkedIn virtualizes the feed (off-screen posts are dropped from the DOM), each item is counted once the moment it is hidden and the running total keeps climbing as you scroll, rather than shrinking. Toggling a category off restores its items and resets its counter. A separator was also added before the relationship-status toggle for visual grouping.

Security

  • Build leak gate (pnpm security:build). A dependency-free script (scripts/check-build-security.mjs) scans every production build dir and fails if it ships a source map (.map, external sourceMappingURL, or inline map / sourcesContent), an original source file, dev-server / HMR code (localhost:3000, vite-hmr, …) or an absolute dev path. It runs in pnpm validate and as a hard stop in the release workflow before anything is published, so a release can never leak source maps or code.
Publicado em 30 de maio de 2026

Removed

  • Dropped Safari support. Packaging a Safari Web Extension requires Xcode, and the MV3 migration it would need (for the stop-feed-refresh world: 'MAIN' content script) leaked the sidePanel config through a WXT browser-detection quirk. All Safari targets, scripts, permissions and docs were removed. The extension now targets Chrome, Edge, Opera, Brave and Firefox.

Changed

  • Firefox is now built as Manifest V3. The stop-feed-refresh tool needs a world: 'MAIN' content script to override LinkedIn's page from inside its strict CSP, and world: 'MAIN' only exists in MV3. Firefox 128+ supports it (already the strict_min_version), so the feature now works on Firefox too. Chrome / Edge / Opera / Brave / Firefox are fully supported. CI builds all four browser targets.

Added

  • Update notifier. Because the extension is installed manually (no store), the background periodically (via chrome.alarms) checks a public releases manifest and shows a one-time notification per version when a newer build is available, linking to the releases page. The options page shows the installed version and a "Check for updates" toggle to disable it entirely. Logic in src/lib/update-check.ts.

Security

  • The extension now makes ONE outbound network request: an anonymous update check. It fetches a public static JSON (…/josedacosta-extensions-releases/…/extension.json) with no query string and no identifier, reading only latestVersion. This relaxes the previous "never phones home" posture; it is opt-out via the checkForUpdates setting and documented in PRIVACY.md. New alarms + notifications permissions back the feature.

Fixed

  • Relationship badge now lands on the post author, not the resharer. On "X liked/commented on this" posts, the badge could attach to the reactor (e.g. a followed company) while showing the author's follow state — so it read "Non abonné" next to a page you actually follow. The 3rd-degree token is rendered "3e et +", which the degree matcher missed (length + missing "et +"), causing the fallback to the wrong actor. The matcher now accepts "3e et +" / "3rd+", so the badge anchors on the author's degree and reflects their relationship. (The notification level — the bell's "All / Most relevant / Off" — is not present in the feed HTML, so it cannot be shown per post.)
Publicado em 30 de maio de 2026

Added

  • Update notifier. Because the extension is installed manually (no store), the background periodically (via chrome.alarms) checks a public releases manifest and shows a one-time notification per version when a newer build is available, linking to the releases page. The options page shows the installed version and a "Check for updates" toggle to disable it entirely. Logic in src/lib/update-check.ts.

Security

  • The extension now makes ONE outbound network request: an anonymous update check. It fetches a public static JSON (…/josedacosta-extensions-releases/…/extension.json) with no query string and no identifier, reading only latestVersion. This relaxes the previous "never phones home" posture; it is opt-out via the checkForUpdates setting and documented in PRIVACY.md. New alarms + notifications permissions back the feature.

Fixed

  • Relationship badge now lands on the post author, not the resharer. On "X liked/commented on this" posts, the badge could attach to the reactor (e.g. a followed company) while showing the author's follow state — so it read "Non abonné" next to a page you actually follow. The 3rd-degree token is rendered "3e et +", which the degree matcher missed (length + missing "et +"), causing the fallback to the wrong actor. The matcher now accepts "3e et +" / "3rd+", so the badge anchors on the author's degree and reflects their relationship. (The notification level — the bell's "All / Most relevant / Off" — is not present in the feed HTML, so it cannot be shown per post.)