Frontend Masters Boost RSS Feed https://frontendmasters.com/blog Helping Your Journey to Senior Developer Thu, 25 Jul 2024 14:10:43 +0000 en-US hourly 1 https://wordpress.org/?v=6.6.1 225069128 Ladybird & Independent Browser Engines https://frontendmasters.com/blog/ladybird/ https://frontendmasters.com/blog/ladybird/#comments Wed, 24 Jul 2024 17:41:41 +0000 https://frontendmasters.com/blog/?p=3132 Web browsers are tens of millions of lines of code written over decades to adhere to long, complex standards specifications and defend against all manner of malicious behavior. I’ve long been convinced that an entirely new browser (not a fork or a skinning) would be impossible to build today. Just scratch pad math, maybe 100 developers making 100k/year could do it over 5 years, so call it a 50m investment on developer power alone. Who ponies that up and why?

Well, Ladybird is giving it a go. They should have 7 full timers soon, and it’s open source so they’ll get help there, and are taking donations. Plus they’ll use some third-party resources to get it done, which should trim down on requirements. It reads like the thing already runs. Their big why is that Google is just too influential — and of course there is already controversy.

There is also Flow as well as Servo, which I’m told is the furthest along of all of them. They should get together on all this if you ask me. I’m happy to admit I was wrong and that it seems like new browser engines aren’t the fiction I thought they were.

]]>
https://frontendmasters.com/blog/ladybird/feed/ 1 3132
The Pitfalls of In-App Browsers https://frontendmasters.com/blog/the-pitfalls-of-in-app-browsers/ https://frontendmasters.com/blog/the-pitfalls-of-in-app-browsers/#comments Wed, 17 Jul 2024 16:07:47 +0000 https://frontendmasters.com/blog/?p=3008 Developing websites for modern mobile devices has a pitfall you may not be aware of: in-app browsers. These are web browsers embedded directly within native mobile apps. So if a link is clicked within a native app (e.g. Instagram or TikTok), it uses the in-app browser instead of switching apps to a dedicated browser app.

While potentially convenient for mobile developers (i.e. users will never leave our app! the businessmen squeal), we’ll discuss the drawbacks for web developers like yourself and your users.

In-app browsers are also referred to as embedded browsers or WebView. These are interchangeable terms.

The Drawbacks

The drawbacks of in-app browsers can be broadly categorized:

Limited functionality

In-app browsers are considerably stripped down when compared to their fully-featured counterparts and typically lack features like bookmarking, UI controls, settings, extensions, and downloads. For for instance a browser extension that a user depends on or help protect their privacy will not work in an in-app browser.

Privacy & security concerns

Because in-app browsers are embedded within a native mobile app, the app developer has control and visibility into the users’ in-app browsing activity. This even extends into being able to inject code into the in-app browser which is a major privacy and security concern. Users are largely unaware and aren’t able to opt-out even if they are.

Inconsistent UI/UX

Because in-app browser implementations are all different, the UI is inconsistent. Further, browsing data like history and bookmarks aren’t shared so users typically need to sign into services they may already be securely signed into in their devices actual browser. This leads to a fragmented and frustrating user experience.

Worse performance

In-app browsers tend to be running outdated browser internals which can cause slower loading times and compatibility issues. Users on slower Internet connections may have the problem exacerbated.

Author Update: Since Apple doesn’t allow apps, even browsers, to use their own rendering engine only Android has the problem of bundling in a custom in-app browser instead of using the system WebView, which may be outdated and have worse performance. On iOS, the built-in WebView is bundled as part of the iOS WebKit. On Android, the default built-in WebView is based on the Blink version and is updated independently of the OS as part of the Chrome update process via Google Play.

Bad Behavior in In-App Browsers

History

In-app browsers have existed since circa 2016, but it wasn’t until 2019 when Thomas Steiner, a Google engineer, published a blog post that dove into Facebook’s iOS and Android apps that a wider audience was made aware of the privacy and security concerns. Thomas discussed the technical details behind how the apps implemented their in-app browsers and stated how in-app browsers can perform man-in-the-middle (MITM) attacks by injecting arbitrary JavaScript code and intercepting network traffic.

Three years later, in 2022, Felix Krause published two blog posts (1, 2) and a tool, inappbrowser.com, which focused on the privacy concerns of iOS apps. Initially this covered apps by Meta (Facebook, Messenger, Instagram) and then followed up with Android and other social media apps including TikTok. Felix’s findings supported Thomas’ from 3 years earlier and showed concerning findings from iOS Instagram: the arbitrary injection of a pcm.js script which Meta claimed to be an “event aggregator” but was also monitoring user interactions in the form of taps and selections. Further cause for concern was TikTok injecting JavaScript that monitors all keyboard inputs along with taps, which is effectively the functionality of a keylogger on third-party sites. TikTok acknowledged the existence of this code but claimed it’s only used for debugging, troubleshooting, and performance monitoring.

Felix’s findings led to a lawsuit being filed against Meta in September 2022. The case was dismissed in October 2023.

Nothing Has Changed

Let’s revisit the behavior of iOS & Android Instagram’s in-app browser at the time of this writing (July 2024). This is done by sharing the two testing links, inappbrowser.com and inappdebugger.com (we’ll discuss this one more shortly), in the app as a direct message or URL in your profile bio. This is so you can actually click on them, as Instagram prevents clickable URLs in places like the descriptions of posts.

Let’s start with iOS. Below is iOS Instagram opening inappbrowser.com and inappdebugger.com in July 2024:

This shows that iOS Instagram is still injecting arbitrary JavaScript code which listens to user clicks along with JavaScript messages.

(Editor note: when testing this I noted that Instagram also appends URL parameters on outgoing links, which may be used to communicate additional information to this injected JavaScript).

Next, Android.

The story on Android is slightly different: there’s still arbitrary JavaScript being injected but it isn’t necessarily listening to events tightly coupled with user interactions.

Unfortunately, not much has changed since Felix’s findings nearly 3 years ago.

Open Web Advocacy wrote a piece earlier this year following the events of Apple threatening to kill web apps.

Debugging & Detecting In-App Browsers

Leveraging the existing excellent work of Felix Krause and Shalanah Dawson we have strategies for debugging and detecting when our websites are being viewed by in-app browsers.

  • https://inappbrowser.com/
    • Attempts to detect if there’s any injected JavaScript code running.
  • https://inappdebugger.com/
    • Attempts to detect you’re in an in-app browser and, if so, which app it is inside of.
    • Additionally provides some debugging tests for if downloads are possible and escape-hatches for getting to an actual device browser.
    • Leverages both inapp-spy and bowser.
  • https://github.com/bowser-js/bowser
    • A browser detection library providing metadata and filtering based on browser version.
  • https://github.com/shalanah/inapp-spy
    • A TypeScript library written by Shalanah Dawson that aids in detecting in-app browsers.

Escaping

Now that we have some tools, let’s look at a example in JavaScript for detecting and redirecting in Android using an intent: link. You’d do this if you simply do not want your website being opened in an in-app browser, and offer a link to users to open it in their default browser instead.

import InAppSpy from "inapp-spy"
const { isInApp } = InAppSpy()

// Your app's full URL, maybe defined build-time for different environments
const url = `https://example.com`
const intentLink = `intent:${url}#Intent;end`

// 1. Detect in-app
if (isInApp) {

  // 2. Attempt to auto-redirect
  window.location.replace(intentLink)
    
  // 3. Append a native <a> with the same intent link
  const $div = document.createElement("div")
  $div.innerHTML = `
    <p>Tap the button to open in your default browser</p>
    <a href="${intentLink}" target="_blank">Open</a>
  `
  document.body.appendChild($div)
}

It’s not ideal to have to load extra JavaScript for this, but it is reliable. This may be heavy handed, but for those of you working on particularly sensitive sites, it might be worth doing.

To get an idea of a way this can be implemented, Shalanah’s inappdebugger.com provides this functionality under the “Android In-App Escape Links” section.

Test out the Android escape hatch strategy on inappdebugger.com.

Unfortunately, there’s currently no reliable way of handling iOS in-app browsers in terms of a proper escape hatch. Similar to Android, there’s a handful of device-specific URI schemes (that’s technically what the intent: prefix is called), but none of them are reliable to the default browser on a specific URL. A not-so-great workaround is using the x-web-search://? scheme, but the best-case is using the site: search prefix to get close to your actual URL e.g. x-web-search://?site:example.com.

Author Update: a somewhat reliable iOS workaround has been documented and tested by trying to run a Shortcut that doesn’t exist, specifying your URL in an error callback, and opening that in the user’s default browser. In practice, this looks like:

shortcuts://x-callback-url/run-shortcut?name=${crypto.randomUUID()}&x-error=${encodeURIComponent('https://example.com')}

This comes with some side effect caveats: the Shortcuts app is opened on the user’s device and some query parameters are appended to your URL. Read more on GitHub.

A last-ditch effort on iOS would be creating a UI element in your web app that gives the user manual instructions for bailing:

  1. Tapping the “…” menu
  2. Tapping on “Open in browser”
Screenshot of a UI that points to the upper right of the screen saying:

1. Click on the overflow menu (•••)
2. Then click Open in browser

This is considerably more fragile and error-prone, but if you have the metrics to where your user traffic is coming from and which in-app browser is preventing them from converting to your feature-rich PWA then it could be worth considering.

Hopefully, with time, we’ll see the fall of in-app browsers. The privacy and security concerns alone are unacceptable. Couple that with the limited functionality and poor user experience, it’s probably best they just went away. Thanks to groups like the Open Web Advocacy and individuals like Shalanah Dawson and Felix Krause for their work and support for this cause.

Recommended Reading

]]>
https://frontendmasters.com/blog/the-pitfalls-of-in-app-browsers/feed/ 1 3008
Harmful design in browser choice https://frontendmasters.com/blog/harmful-design-in-browser-choice/ https://frontendmasters.com/blog/harmful-design-in-browser-choice/#respond Mon, 12 Feb 2024 17:39:07 +0000 https://frontendmasters.com/blog/?p=790 Props to Cennydd Bowles and Harry Bringnull for calling out this poor behavior on Microsoft’s part. Microsoft Edge is literally injecting a big banner on Chrome’s download page telling people that Edge is better.

Of all Microsoft’s tactics, the most objectionable for me is their dissuasive messaging injected directly into the Chrome download page. As we write, ‘for a browser vendor to interfere with the contents of a competitor’s website – or indeed any website – with neither due cause nor user consent is highly irregular and ethically indefensible.’

We need to cry foul when browser vendors mess with the actual content on websites. While this just looks like two behemoths clashing heads, how would you feel about Microsoft making editorial choices on your website?

]]>
https://frontendmasters.com/blog/harmful-design-in-browser-choice/feed/ 0 790
Everybody Has All the Power and Everything At Stake https://frontendmasters.com/blog/everybody-has-all-the-power-and-everything-at-stake/ https://frontendmasters.com/blog/everybody-has-all-the-power-and-everything-at-stake/#comments Wed, 24 Jan 2024 18:18:18 +0000 https://frontendmasters.com/blog/?p=592 Here’s a little thought about the precarious relationship we live with on the web.

As web developers, we have very little power over the platforms we build on. We’re given what we’re given, we use what we get. We can say what we want, but it may or may not have any influence; there are lots of examples of both directions. We’re like armchair quarterbacks, cheering or jeering that over which we cannot control.

We also have lots of power, especially as a collective. We don’t have to use any particular features. We can do whatever we want. We don’t have to build websites at all. We generally want to use the web because it’s useful for a wide array of objectives, but they are always other means to an end. The web is meaningless without all the people who build sites and maintain them.

The companies that build the platforms are in the same boat. These companies have little power in what the entire industry does. They are at the whim of giant swings in user behavior and sentiment.

Those companies also have lots of power. They can do whatever they want with the platforms. They own them entirely. They make every decision.

Thus, this whole dance has to be symbiotic. There is a lot of incentive on both sides to keep dancing, so we will. But it’s still precarious. Either side can take their ball and go home.

Me, I’m optimistic. The web is very high up the list of the best things human beings have ever done, so let’s keep choosing it and making it better.

]]>
https://frontendmasters.com/blog/everybody-has-all-the-power-and-everything-at-stake/feed/ 1 592