{"id":730,"date":"2026-10-29T10:00:00","date_gmt":"2026-10-29T10:00:00","guid":{"rendered":"https:\/\/zydeno.com\/?p=730"},"modified":"2026-10-29T10:00:00","modified_gmt":"2026-10-29T10:00:00","slug":"trasformare-unapp-per-telefono-in-unestensione-per-browser","status":"publish","type":"post","link":"https:\/\/zydeno.com\/it\/trasformare-unapp-per-telefono-in-unestensione-per-browser\/","title":{"rendered":"Trasferimento di un'app per telefono in un'estensione per browser"},"content":{"rendered":"<p>KeyRush \u00e8 nato su iPhone e Android. Quando abbiamo deciso di portarlo su Chrome, ci siamo trovati di fronte a una scelta: avvolgere l\u2019app esistente in un livello multipiattaforma oppure riscriverla per il browser. Abbiamo optato per la riscrittura, effettuando il porting dalla versione Android. Solo JavaScript, Manifest V3, nessun framework e nessuna fase di compilazione. Ecco cosa abbiamo imparato da questa esperienza.<\/p>\n<h2>La tastiera \u00e8 ormai una realt\u00e0<\/h2>\n<p>Su uno smartphone, un programma per imparare a digitare \u00e8 una soluzione approssimativa. La tastiera su schermo \u00e8 allo stesso tempo il dispositivo di input e l\u2019oggetto dell\u2019apprendimento, il che crea una situazione un po\u2019 strana. Nel browser, invece, l\u2019utente ha sotto le dita una tastiera vera e propria \u2014 proprio ci\u00f2 che l\u2019app sta cercando di insegnare.<\/p>\n<p>La situazione si \u00e8 rivelata molto diversa da quanto ci aspettassimo. Le disposizioni dei tasti variano da un paese all\u2019altro e da una tastiera all\u2019altra. Esistono i tasti modificatori. Gli utenti tengono premuti i tasti, ne premono due contemporaneamente, cambiano disposizione durante la sessione. Su una tastiera fisica ogni minima imprecisione nel simulatore si avverte immediatamente, quindi abbiamo dovuto prestare molta pi\u00f9 attenzione a ci\u00f2 che viene considerato un tasto premuto correttamente.<\/p>\n<p>Abbiamo mantenuto la tastiera su schermo, ma la sua funzione \u00e8 cambiata. Su uno smartphone \u00e8 ci\u00f2 che si preme. Nell\u2019estensione funge da guida: evidenzia il tasto che si deve premere successivamente, cos\u00ec puoi tenere gli occhi sullo schermo invece che sulle mani. \u00c8 proprio questo il senso della digitazione cieca, e il browser ci ha permesso di prenderla sul serio.<\/p>\n<h2>Le dimensioni delle finestre non sono fisse<\/h2>\n<p>Gli schermi dei telefoni sono disponibili in poche forme diverse. Le finestre del browser, invece, possono assumere qualsiasi forma. Il popup di un'estensione \u00e8 stretto e corto; una scheda a schermo intero pu\u00f2 essere enorme. La stessa app doveva risultare intuitiva in entrambi i casi.<\/p>\n<p>Quindi offriamo entrambe le opzioni. KeyRush si apre come finestra pop-up per un test veloce e in una scheda a schermo intero quando serve pi\u00f9 spazio per le lezioni e le gare. La combinazione Alt+Shift+K permette di aprirlo senza dover usare il mouse \u2014 il che, per un\u2019app di digitazione, ci \u00e8 sembrata l\u2019impostazione predefinita pi\u00f9 appropriata.<\/p>\n<h2>I popup dimenticano tutto<\/h2>\n<p>Un popup si chiude non appena si fa clic al di fuori di esso, e tutto ci\u00f2 che occupava in memoria viene eliminato. Su Android, un'app pu\u00f2 essere messa in secondo piano e riprendere esattamente da dove era stata interrotta. In un popup, bisogna partire dal presupposto che l'utente possa chiudere la finestra in qualsiasi momento.<\/p>\n<p>Quindi tutto ci\u00f2 che conta risiede nella memoria del browser piuttosto che nella finestra, e sia la finestra pop-up che la scheda a schermo intero leggono dallo stesso stato memorizzato. Una volta completato un test nella finestra pop-up, basta aprire la scheda a schermo intero e il risultato \u00e8 gi\u00e0 l\u00ec. \u00c8 una piccola scelta architettonica che ha reso l'intera estensione pi\u00f9 solida.<\/p>\n<h2>Le autorizzazioni sono una scelta progettuale<\/h2>\n<p>Anche le app Android richiedono autorizzazioni, ma gli utenti le leggono raramente. Gli utenti delle estensioni, invece, lo fanno spesso, e il browser mostra gli avvisi direttamente nella finestra di installazione. KeyRush ne richiede esattamente una: l\u2019accesso alla memoria. Non ha bisogno di vedere le pagine che visiti, quindi non te lo chiede. Abbiamo scritto un post a parte sul motivo per cui questo \u00e8 importante per noi.<\/p>\n<h2>Quello che abbiamo conservato<\/h2>\n<p>Quasi tutto il contenuto del prodotto \u00e8 rimasto invariato: prove di velocit\u00e0 cronometrate da 15, 30, 60 e 120 secondi, lezioni di dattilografia organizzate per dito, gare contro avversari virtuali, statistiche, una mappa termica dei tasti sbagliati, la sfida quotidiana e tutti i 44 obiettivi. Chi passa dall\u2019app per smartphone alla versione desktop dovrebbe sentirsi a proprio agio nel giro di un minuto.<\/p>\n<p>Abbiamo mantenuto anche i principi fondamentali. Funziona completamente offline. I progressi vengono salvati esclusivamente nel browser. Non c'\u00e8 alcun account e non \u00e8 necessario effettuare alcun accesso.<\/p>\n<h2>Perch\u00e9 non abbiamo condiviso il codice<\/h2>\n<p>Riscrivere il codice sembrava costoso, e in un certo senso lo \u00e8 stato. Ma un programma per imparare a digitare non \u00e8 un\u2019app di grandi dimensioni, e la logica fondamentale \u2014 punteggio, lezioni, livelli, obiettivi raggiunti \u2014 \u00e8 abbastanza snella da poter essere trasferita con cura a mano dall\u2019originale Android. In cambio abbiamo ottenuto un'estensione che si carica all'istante, non presenta dipendenze da terze parti da mantenere aggiornate e si comporta come se fosse stata creata appositamente per il browser, perch\u00e9 \u00e8 proprio cos\u00ec.<\/p>","protected":false},"excerpt":{"rendered":"<p>Cosa \u00e8 cambiato quando KeyRush \u00e8 passato da Android a Chrome \u2014 e cosa ci siamo rifiutati di cambiare.<\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-730","post","type-post","status-publish","format-standard","hentry","category-journal"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v22.2 (Yoast SEO v22.2) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Porting a phone app to a browser extension - Zydeno Studio<\/title>\n<meta name=\"description\" content=\"Lessons from porting the KeyRush typing trainer from Android to a Manifest V3 Chrome extension: real keyboards, popups, window sizes and permissions.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/zydeno.com\/it\/trasformare-unapp-per-telefono-in-unestensione-per-browser\/\" \/>\n<meta property=\"og:locale\" content=\"it_IT\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Porting a phone app to a browser extension\" \/>\n<meta property=\"og:description\" content=\"Lessons from porting the KeyRush typing trainer from Android to a Manifest V3 Chrome extension: real keyboards, popups, window sizes and permissions.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/zydeno.com\/it\/trasformare-unapp-per-telefono-in-unestensione-per-browser\/\" \/>\n<meta property=\"og:site_name\" content=\"Zydeno Studio\" \/>\n<meta property=\"article:published_time\" content=\"2026-10-29T10:00:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/zydeno.com\/wp-content\/uploads\/2026\/10\/zydeno-social.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Andrii Matiushev\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Scritto da\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andrii Matiushev\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tempo di lettura stimato\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minuti\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":[\"Article\",\"BlogPosting\"],\"@id\":\"https:\/\/zydeno.com\/porting-a-phone-app-to-a-browser-extension\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/zydeno.com\/porting-a-phone-app-to-a-browser-extension\/\"},\"author\":{\"name\":\"Andrii Matiushev\",\"@id\":\"https:\/\/zydeno.com\/#\/schema\/person\/1af4d0e254f05b407f306ede28252259\"},\"headline\":\"Porting a phone app to a browser extension\",\"datePublished\":\"2026-10-29T10:00:00+00:00\",\"dateModified\":\"2026-10-29T10:00:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/zydeno.com\/porting-a-phone-app-to-a-browser-extension\/\"},\"wordCount\":666,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/zydeno.com\/#organization\"},\"articleSection\":[\"Journal\"],\"inLanguage\":\"it-IT\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/zydeno.com\/porting-a-phone-app-to-a-browser-extension\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/zydeno.com\/porting-a-phone-app-to-a-browser-extension\/\",\"url\":\"https:\/\/zydeno.com\/porting-a-phone-app-to-a-browser-extension\/\",\"name\":\"Porting a phone app to a browser extension - Zydeno Studio\",\"isPartOf\":{\"@id\":\"https:\/\/zydeno.com\/#website\"},\"datePublished\":\"2026-10-29T10:00:00+00:00\",\"dateModified\":\"2026-10-29T10:00:00+00:00\",\"description\":\"Lessons from porting the KeyRush typing trainer from Android to a Manifest V3 Chrome extension: real keyboards, popups, window sizes and permissions.\",\"breadcrumb\":{\"@id\":\"https:\/\/zydeno.com\/porting-a-phone-app-to-a-browser-extension\/#breadcrumb\"},\"inLanguage\":\"it-IT\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/zydeno.com\/porting-a-phone-app-to-a-browser-extension\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/zydeno.com\/porting-a-phone-app-to-a-browser-extension\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/zydeno.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Porting a phone app to a browser extension\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/zydeno.com\/#website\",\"url\":\"https:\/\/zydeno.com\/\",\"name\":\"Zydeno Studio\",\"description\":\"Zydeno is an indie studio designing apps across many categories \u2014 united by a shared obsession with craft and detail. Fast, opinionated, independent apps for iPhone, Android, Windows and Mac, plus extensions for Chrome, Edge and Firefox. Built slowly, shipped carefully.\",\"publisher\":{\"@id\":\"https:\/\/zydeno.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/zydeno.com\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"it-IT\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/zydeno.com\/#organization\",\"name\":\"Zydeno Studio\",\"url\":\"https:\/\/zydeno.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"it-IT\",\"@id\":\"https:\/\/zydeno.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/zydeno.com\/wp-content\/uploads\/2026\/04\/cropped-icon-512-1.png\",\"contentUrl\":\"https:\/\/zydeno.com\/wp-content\/uploads\/2026\/04\/cropped-icon-512-1.png\",\"width\":512,\"height\":512,\"caption\":\"Zydeno Studio\"},\"image\":{\"@id\":\"https:\/\/zydeno.com\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/zydeno.com\/#\/schema\/person\/1af4d0e254f05b407f306ede28252259\",\"name\":\"Andrii Matiushev\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"it-IT\",\"@id\":\"https:\/\/zydeno.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/4df57b6b4737601c798e728e7d4d209a9a9513422db2b613ff707286cb1ea58a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/4df57b6b4737601c798e728e7d4d209a9a9513422db2b613ff707286cb1ea58a?s=96&d=mm&r=g\",\"caption\":\"Andrii Matiushev\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Come convertire un'app per smartphone in un'estensione per browser - Zydeno Studio","description":"Lezioni apprese dal porting del programma di esercitazione alla digitazione KeyRush da Android a un'estensione Chrome per Manifest V3: tastiere reali, finestre a comparsa, dimensioni delle finestre e autorizzazioni.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/zydeno.com\/it\/trasformare-unapp-per-telefono-in-unestensione-per-browser\/","og_locale":"it_IT","og_type":"article","og_title":"Porting a phone app to a browser extension","og_description":"Lessons from porting the KeyRush typing trainer from Android to a Manifest V3 Chrome extension: real keyboards, popups, window sizes and permissions.","og_url":"https:\/\/zydeno.com\/it\/trasformare-unapp-per-telefono-in-unestensione-per-browser\/","og_site_name":"Zydeno Studio","article_published_time":"2026-10-29T10:00:00+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/zydeno.com\/wp-content\/uploads\/2026\/10\/zydeno-social.png","type":"image\/png"}],"author":"Andrii Matiushev","twitter_card":"summary_large_image","twitter_misc":{"Scritto da":"Andrii Matiushev","Tempo di lettura stimato":"3 minuti"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":["Article","BlogPosting"],"@id":"https:\/\/zydeno.com\/porting-a-phone-app-to-a-browser-extension\/#article","isPartOf":{"@id":"https:\/\/zydeno.com\/porting-a-phone-app-to-a-browser-extension\/"},"author":{"name":"Andrii Matiushev","@id":"https:\/\/zydeno.com\/#\/schema\/person\/1af4d0e254f05b407f306ede28252259"},"headline":"Porting a phone app to a browser extension","datePublished":"2026-10-29T10:00:00+00:00","dateModified":"2026-10-29T10:00:00+00:00","mainEntityOfPage":{"@id":"https:\/\/zydeno.com\/porting-a-phone-app-to-a-browser-extension\/"},"wordCount":666,"commentCount":0,"publisher":{"@id":"https:\/\/zydeno.com\/#organization"},"articleSection":["Journal"],"inLanguage":"it-IT","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/zydeno.com\/porting-a-phone-app-to-a-browser-extension\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/zydeno.com\/porting-a-phone-app-to-a-browser-extension\/","url":"https:\/\/zydeno.com\/porting-a-phone-app-to-a-browser-extension\/","name":"Come convertire un'app per smartphone in un'estensione per browser - Zydeno Studio","isPartOf":{"@id":"https:\/\/zydeno.com\/#website"},"datePublished":"2026-10-29T10:00:00+00:00","dateModified":"2026-10-29T10:00:00+00:00","description":"Lezioni apprese dal porting del programma di esercitazione alla digitazione KeyRush da Android a un'estensione Chrome per Manifest V3: tastiere reali, finestre a comparsa, dimensioni delle finestre e autorizzazioni.","breadcrumb":{"@id":"https:\/\/zydeno.com\/porting-a-phone-app-to-a-browser-extension\/#breadcrumb"},"inLanguage":"it-IT","potentialAction":[{"@type":"ReadAction","target":["https:\/\/zydeno.com\/porting-a-phone-app-to-a-browser-extension\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/zydeno.com\/porting-a-phone-app-to-a-browser-extension\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/zydeno.com\/"},{"@type":"ListItem","position":2,"name":"Porting a phone app to a browser extension"}]},{"@type":"WebSite","@id":"https:\/\/zydeno.com\/#website","url":"https:\/\/zydeno.com\/","name":"Zydeno Studio","description":"Zydeno \u00e8 uno studio indipendente che sviluppa app in diverse categorie, accomunate da una comune passione per la qualit\u00e0 artigianale e l\u2019attenzione ai dettagli. App veloci, con una forte personalit\u00e0 e indipendenti per iPhone, Android, Windows e Mac, oltre a estensioni per Chrome, Edge e Firefox. Realizzate con calma, lanciate con cura.","publisher":{"@id":"https:\/\/zydeno.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/zydeno.com\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"it-IT"},{"@type":"Organization","@id":"https:\/\/zydeno.com\/#organization","name":"Zydeno Studio","url":"https:\/\/zydeno.com\/","logo":{"@type":"ImageObject","inLanguage":"it-IT","@id":"https:\/\/zydeno.com\/#\/schema\/logo\/image\/","url":"https:\/\/zydeno.com\/wp-content\/uploads\/2026\/04\/cropped-icon-512-1.png","contentUrl":"https:\/\/zydeno.com\/wp-content\/uploads\/2026\/04\/cropped-icon-512-1.png","width":512,"height":512,"caption":"Zydeno Studio"},"image":{"@id":"https:\/\/zydeno.com\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/zydeno.com\/#\/schema\/person\/1af4d0e254f05b407f306ede28252259","name":"Andrii Matiushev","image":{"@type":"ImageObject","inLanguage":"it-IT","@id":"https:\/\/zydeno.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/4df57b6b4737601c798e728e7d4d209a9a9513422db2b613ff707286cb1ea58a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/4df57b6b4737601c798e728e7d4d209a9a9513422db2b613ff707286cb1ea58a?s=96&d=mm&r=g","caption":"Andrii Matiushev"}}]}},"_links":{"self":[{"href":"https:\/\/zydeno.com\/it\/wp-json\/wp\/v2\/posts\/730","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/zydeno.com\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/zydeno.com\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/zydeno.com\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/zydeno.com\/it\/wp-json\/wp\/v2\/comments?post=730"}],"version-history":[{"count":1,"href":"https:\/\/zydeno.com\/it\/wp-json\/wp\/v2\/posts\/730\/revisions"}],"predecessor-version":[{"id":917,"href":"https:\/\/zydeno.com\/it\/wp-json\/wp\/v2\/posts\/730\/revisions\/917"}],"wp:attachment":[{"href":"https:\/\/zydeno.com\/it\/wp-json\/wp\/v2\/media?parent=730"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/zydeno.com\/it\/wp-json\/wp\/v2\/categories?post=730"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/zydeno.com\/it\/wp-json\/wp\/v2\/tags?post=730"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}