Modern Mobile Bookmarklets with the ShareTarget API

Bookmarklets are an unsung superpower of Desktop Web Browsers. They are not as powerful as Chrome Extensions, they require a user gesture, they don’t have access to browser specific API’s (such as chrome.*), yet I love them. In their simplest form (a Bookmark) they navigate you to a URL; more complex forms (Bookmarklets) navigate to a javascript: URL which means you can run simple automated actions that run in the context of the page, creating functionality that the original developer didn’t get around to creating just yet, just at the click of a button.


This content originally appeared on Modern Web Development with Chrome and was authored by Paul Kinlan

<p>Bookmarklets are an unsung superpower of Desktop Web Browsers. They are not as powerful as Chrome Extensions, they require a user gesture, they don't have access to browser specific API's (such as chrome.*), yet I love them. In their simplest form (a Bookmark) they navigate you to a URL; more complex forms (Bookmarklets) navigate to a <code>javascript:</code> URL which means you can run simple automated actions that run in the context of the page, creating functionality that the original developer didn't get around to creating just yet, just at the click of a button.</p> <p>I create Bookmarklets all the time. Most of the Bookmarklets that I create are relatively simple, they take some data from the page, manipulate it and then call another page or app with that data. For example, this <a href="https://paul.kinlan.me/bookmarklet-trace-page/">bookmarklet</a> inspect the performance of the page you are on.</p> <p>Bookmarklets on mobile are a different story altogether, they don't exist. I am not sure of the reasoning, but I think there is a way around to support basic Bookmarklets in Browser's that support the <code>ShareTarget</code> API.</p> <p>The <a href="https://paul.kinlan.me/file-web-share-target/">ShareTarget API</a> is a new feature in the browser that lets a user install your web app and receive native Share Actions. The Twitter PWA is a great example of this in action, you can share links and files directly to the web app from any part of the Android system. </p> <p><code>ShareTarget</code> has two components, a description of how to get data in a manifest file, and the fetch handler in a service worker. When the user shares to an installed PWA it will create an HTTP POST request to the end-point defined in the manifest, and then it's up to you to handle the POST in the <code>onfetch</code> handler.</p> <p>With this in mind, I believe you can solve a lot of use cases you need Bookmarklets for via this API.</p> <p>I wrote three simple 'Share' actions for services that I don't expect to implement a Share Action any time soon - <a href="https://github.com/PaulKinlan/hn-share-target">Hacker News</a>, <a href="https://github.com/PaulKinlan/reddit-share-target">Reddit</a>, and <a href="https://github.com/PaulKinlan/linkedinposter">LinkedIn</a>. Now, if you visit <a href="https://hn-share.now.sh/">https://hn-share.now.sh/</a> you can install this small PWA and share any URL to it from any App on your Android device. The best thing was it wasn't as complex as I thought it might be.</p> <p>First you define your 'mini-app' in your <a href="https://github.com/PaulKinlan/hn-share-target/blob/master/site/manifest.json">web app manifest file</a>, and configure the <code>share_target</code> object.</p> <div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-JavaScript" data-lang="JavaScript">{ <span style="color:#e6db74">"name"</span><span style="color:#f92672">:</span> <span style="color:#e6db74">"Share to HackerNews"</span>, <span style="color:#e6db74">"short_name"</span><span style="color:#f92672">:</span> <span style="color:#e6db74">"HN Share"</span>, <span style="color:#e6db74">"start_url"</span><span style="color:#f92672">:</span> <span style="color:#e6db74">"/"</span>, <span style="color:#e6db74">"theme_color"</span><span style="color:#f92672">:</span> <span style="color:#e6db74">"#000000"</span>, <span style="color:#e6db74">"background_color"</span><span style="color:#f92672">:</span> <span style="color:#e6db74">"#000000"</span>, <span style="color:#e6db74">"icons"</span><span style="color:#f92672">:</span> [ { <span style="color:#e6db74">"sizes"</span><span style="color:#f92672">:</span> <span style="color:#e6db74">"192x192"</span>, <span style="color:#e6db74">"src"</span><span style="color:#f92672">:</span> <span style="color:#e6db74">"/images/me.png"</span>, <span style="color:#e6db74">"type"</span><span style="color:#f92672">:</span> <span style="color:#e6db74">"image/png"</span> }, { <span style="color:#e6db74">"sizes"</span><span style="color:#f92672">:</span> <span style="color:#e6db74">"512x512"</span>, <span style="color:#e6db74">"src"</span><span style="color:#f92672">:</span> <span style="color:#e6db74">"/images/me.png"</span>, <span style="color:#e6db74">"type"</span><span style="color:#f92672">:</span> <span style="color:#e6db74">"image/png"</span> } ], <span style="color:#e6db74">"share_target"</span><span style="color:#f92672">:</span> { <span style="color:#e6db74">"action"</span><span style="color:#f92672">:</span> <span style="color:#e6db74">"/share.html"</span>, <span style="color:#e6db74">"method"</span><span style="color:#f92672">:</span> <span style="color:#e6db74">"GET"</span>, <span style="color:#e6db74">"enctype"</span><span style="color:#f92672">:</span> <span style="color:#e6db74">"application/x-www-form-urlencoded"</span>, <span style="color:#e6db74">"params"</span><span style="color:#f92672">:</span> { <span style="color:#e6db74">"title"</span><span style="color:#f92672">:</span> <span style="color:#e6db74">"title"</span>, <span style="color:#e6db74">"text"</span><span style="color:#f92672">:</span> <span style="color:#e6db74">"text"</span>, <span style="color:#e6db74">"url"</span><span style="color:#f92672">:</span> <span style="color:#e6db74">"url"</span> } }, <span style="color:#e6db74">"display"</span><span style="color:#f92672">:</span> <span style="color:#e6db74">"standalone"</span>, <span style="color:#e6db74">"scope"</span><span style="color:#f92672">:</span> <span style="color:#e6db74">"/"</span> } </code></pre></div><p>Then in the <a href="https://github.com/PaulKinlan/hn-share-target/blob/master/site/sw.js">service worker</a> handle the <code>POST</code> method in the <code>onfetch</code> handler.</p> <div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-JavaScript" data-lang="JavaScript"><span style="color:#a6e22e">onfetch</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">async</span> (<span style="color:#a6e22e">event</span>) => { <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">url</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> <span style="color:#a6e22e">URL</span>(<span style="color:#a6e22e">event</span>.<span style="color:#a6e22e">request</span>.<span style="color:#a6e22e">url</span>); <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">event</span>.<span style="color:#a6e22e">request</span>.<span style="color:#a6e22e">method</span> <span style="color:#f92672">!==</span> <span style="color:#e6db74">'POST'</span>) <span style="color:#66d9ef">return</span>; <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">location</span> <span style="color:#f92672">=</span> encodeURIComponent(<span style="color:#a6e22e">url</span>.<span style="color:#a6e22e">searchParams</span>.<span style="color:#a6e22e">get</span>(<span style="color:#e6db74">'url'</span>) <span style="color:#f92672">||</span> <span style="color:#a6e22e">url</span>.<span style="color:#a6e22e">searchParams</span>.<span style="color:#a6e22e">get</span>(<span style="color:#e6db74">'text'</span>)); <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">title</span> <span style="color:#f92672">=</span> encodeURIComponent(<span style="color:#a6e22e">url</span>.<span style="color:#a6e22e">searchParams</span>.<span style="color:#a6e22e">get</span>(<span style="color:#e6db74">'title'</span>)) <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">hnUrl</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">`https://news.ycombinator.com/submitlink?u=</span><span style="color:#e6db74">${</span><span style="color:#a6e22e">location</span><span style="color:#e6db74">}</span><span style="color:#e6db74">&t=</span><span style="color:#e6db74">${</span><span style="color:#a6e22e">title</span><span style="color:#e6db74">}</span><span style="color:#e6db74">`</span> <span style="color:#a6e22e">event</span>.<span style="color:#a6e22e">waitUntil</span>(<span style="color:#a6e22e">event</span>.<span style="color:#a6e22e">respondWith</span>(<span style="color:#a6e22e">Response</span>.<span style="color:#a6e22e">redirect</span>(<span style="color:#a6e22e">hnUrl</span>))); }; <span style="color:#a6e22e">oninstall</span> <span style="color:#f92672">=</span> () => { <span style="color:#a6e22e">skipWaiting</span>(); }; <span style="color:#a6e22e">onactivate</span> <span style="color:#f92672">=</span> () => { <span style="color:#a6e22e">clients</span>.<span style="color:#a6e22e">claim</span>(); }; </code></pre></div><p>It is this last piece where you control what happens to the user - in this case I forward the user to the 'Share URL' of the service that is installed. You could do more complex actions too - for example, Imgur has an API and if you were integrating with that service you could upload an attached image and then redirect the user to the upload results page.</p> <p>Whilst this doesn't offer exactly the same functionality as Desktop Bookmarklets, the idea does offer a new level of hackability for mobile web experiences and I would love to see what you build.</p>


This content originally appeared on Modern Web Development with Chrome and was authored by Paul Kinlan


Print Share Comment Cite Upload Translate Updates
APA

Paul Kinlan | Sciencx (2019-12-18T13:48:22+00:00) Modern Mobile Bookmarklets with the ShareTarget API. Retrieved from https://www.scien.cx/2019/12/18/modern-mobile-bookmarklets-with-the-sharetarget-api/

MLA
" » Modern Mobile Bookmarklets with the ShareTarget API." Paul Kinlan | Sciencx - Wednesday December 18, 2019, https://www.scien.cx/2019/12/18/modern-mobile-bookmarklets-with-the-sharetarget-api/
HARVARD
Paul Kinlan | Sciencx Wednesday December 18, 2019 » Modern Mobile Bookmarklets with the ShareTarget API., viewed ,<https://www.scien.cx/2019/12/18/modern-mobile-bookmarklets-with-the-sharetarget-api/>
VANCOUVER
Paul Kinlan | Sciencx - » Modern Mobile Bookmarklets with the ShareTarget API. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2019/12/18/modern-mobile-bookmarklets-with-the-sharetarget-api/
CHICAGO
" » Modern Mobile Bookmarklets with the ShareTarget API." Paul Kinlan | Sciencx - Accessed . https://www.scien.cx/2019/12/18/modern-mobile-bookmarklets-with-the-sharetarget-api/
IEEE
" » Modern Mobile Bookmarklets with the ShareTarget API." Paul Kinlan | Sciencx [Online]. Available: https://www.scien.cx/2019/12/18/modern-mobile-bookmarklets-with-the-sharetarget-api/. [Accessed: ]
rf:citation
» Modern Mobile Bookmarklets with the ShareTarget API | Paul Kinlan | Sciencx | https://www.scien.cx/2019/12/18/modern-mobile-bookmarklets-with-the-sharetarget-api/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.