Ricostruire il Save to PDF di LinkedIn: un'estensione che gira tutta sul client
LinkedIn ha rimosso, senza clamore, la sua opzione “Save to PDF”. Per chi cerca lavoro, recluta o semplicemente archivia un profilo, è sparita un’esportazione in un click. Così l’ho ricostruita, come estensione Chrome open-source, con un vincolo fermo: doveva girare tutta sul client. L’obiettivo non era solo riportare la funzione, ma arrivare a un’esportazione migliore di quella di LinkedIn.
Il vincolo che ha definito tutto
Nessun server, nessun account, nessun tracking. Ogni passo, leggere il profilo,
costruire il layout, generare il PDF, avviene dentro il tuo browser. L’unico
storage che tocca è chrome.storage.local, usato brevemente per passare i dati
estratti alla vista di stampa, e cancellato nel momento in cui il PDF viene
prodotto. Non si raccoglie e non si trasmette nulla.
Quel vincolo non è una frase di marketing, è una decisione di architettura. Un profilo è dato personale. Nel momento in cui lo mandi a un server per “elaborarlo”, ti ritrovi un problema di privacy: log, retention, superficie di attacco, una privacy policy da rispettare. Tenere tutto in locale elimina quell’intera classe di problemi. Il compromesso è che il browser deve fare tutto il lavoro, senza un backend su cui appoggiarsi.
La parte difficile: niente API, un DOM che si muove, e troncamento
LinkedIn non ha un’API pubblica per questo, quindi l’estensione legge la pagina renderizzata tramite content script. Con il solito dolore: il DOM cambia, il markup è profondamente annidato, e il profilo si renderizza nella lingua che usa l’account. Il parsing è strutturale e non basato sul testo, quindi funziona con profili LinkedIn in qualsiasi lingua.
Il problema più duro è il troncamento. La pagina principale del profilo mostra
solo le prime voci di esperienza, formazione e competenze; il resto sta dietro
“Mostra tutto”. Per catturare tutto, il Full Profile Export opzionale apre le
pagine /details/<sezione>/ dello stesso profilo in schede temporanee in
background, una alla volta, legge le liste complete e le chiude. È più lento ed è
opt-in, ma recupera le sezioni che un’esportazione semplice perderebbe.
Generare il PDF
Non c’è nessuna libreria PDF impacchettata. L’estensione costruisce una vista pulita ottimizzata per la stampa e usa il print-to-PDF nativo del browser. Questo mantiene l’estensione piccola, evita di spedire un motore di rendering, e produce un output basato su testo, selezionabile e ATS-friendly invece di un’immagine appiattita. La vista di stampa renderizza in modalità chiara per risultati coerenti, e scegli quali sezioni includere: foto, contatti, esperienza, formazione, competenze.
C’è anche un lato ATS. Il PDF originale di LinkedIn è stato pensato per la stampa, non necessariamente per gli applicant tracking system, e il suo layout a due colonne è esattamente il tipo di struttura con cui quei parser faticano. L’estensione, invece, genera un documento semplice a una colonna con testo selezionabile, più facile da leggere in ordine sia per gli umani sia per i parser ATS.
Un click, o il profilo completo
L’estensione offre due modalità, e conviene allinearle al PDF di LinkedIn. L’export
1-click è istantaneo e copre l’essenziale. Il Deep export apre le pagine troncate
/details/ per ricostruire il profilo completo. Il PDF integrato di LinkedIn sta
nel mezzo, in un layout a due colonne che i parser ATS tendono a rifiutare. Stesso
profilo, tre esportazioni:
| PDF di LinkedIn | Export 1-click | Deep export | |
|---|---|---|---|
| Un click, istantaneo | ✓ | ✓ | ✗ |
| Foto profilo | ✗ | ✓ | ✓ |
| Descrizioni complete di ogni ruolo | ✓ | ✗ | ✓ |
| Tutte le competenze, non solo le prime | ✗ | ✗ | ✓ |
| Tutte le lingue | ✓ | ✗ | ✓ |
| Scegliere quali sezioni includere | ✗ | ✓ | ✓ |
| Una colonna, ATS-friendly | ✗ | ✓ | ✓ |
| Generato in locale, niente esce dal browser | ✗ | ✓ | ✓ |
Voce per voce, l’estensione produce il documento migliore. Il Deep export è strettamente più completo del PDF di LinkedIn: mantiene la foto e recupera ogni descrizione di ruolo, ogni competenza e ogni lingua, ed esce come testo pulito, a una colonna, ATS-friendly e generato interamente sulla tua macchina. L’unico vantaggio che resta a LinkedIn è il click istantaneo, ed è esattamente ciò che eguaglia la modalità 1-click. Così hai entrambe le cose: istantaneo quando vuoi velocità, completo quando vuoi tutto, e in nessun caso il tuo profilo esce dal browser.
Le decisioni di ingegneria
Per chi costruisce, le parti in movimento sono volutamente poche. È un’estensione Manifest V3, e ogni pezzo ha un solo compito:
- I content script leggono il profilo renderizzato direttamente dalla pagina.
- Un service worker in background orchestra il Full Profile Export, aprendo e chiudendo schede temporanee una alla volta.
chrome.storage.localtrasporta brevemente i dati estratti alla vista di stampa, poi viene ripulito.window.print()aziona il print-to-PDF nativo del browser, così nessun motore di rendering viene spedito con l’estensione.- Selettori strutturali e indipendenti dalla lingua puntano al DOM per forma e non per testo, così il parser sopravvive a un profilo in qualsiasi lingua.
- Un set di permessi ristretto,
activeTab,storage,scriptingetabs, limitato ahttps://*.linkedin.com/*e niente altro.
Chiunque può verificare esattamente cosa può toccare, cosa che conta per uno strumento che gestisce dati di profilo. Il tema ricorrente è fallire con grazia: senza un’API, ogni selettore è una scommessa su come LinkedIn renderizza oggi, quindi il parser è fatto per degradare invece di rompersi. Il tutto è open source.
Cosa mi ha insegnato costruirla
Costruire l’estensione mi ha ricordato che le estensioni del browser sono spesso più vicine all’ingegneria dei sistemi che allo sviluppo frontend. Senza un’API, ogni release dipende dal capire come un’altra applicazione renderizza la sua interfaccia, dall’anticipare il cambiamento e dal progettare parser che falliscono con grazia. L’interfaccia è la parte facile. La parte difficile è che ti stai integrando con una superficie che nessuno ha progettato per essere integrata, e che si muove sotto i tuoi piedi.
Installare e codice
- Chrome Web Store: LinkedIn Save to PDF (Ingenarte)
- Codice: github.com/Ingenarte/Linkedin_Save_to_PDF
Conclusione
L’obiettivo originale era semplicemente riportare una funzione mancante. È diventato un esercizio di architettura privacy-first, automazione del browser, parsing del DOM e progettazione di software che tiene i dati personali esattamente dove sono già: sulla macchina dell’utente. Questa è la parte che terrei. Per uno strumento che legge il profilo di qualcuno, il default giusto è fare il lavoro dove vive il dato, e non lasciarlo mai uscire.