joseph schmitt

Safari X-Success

Back, back, back it up!

Mar 03 2014

Fork me on GitHub

My favorite feature in Chrome for iOS is its support for a part of the x-callback-url protocol called x-success. The x-success parameter is used to tell an application that conforms to the protocol what to do after the primary action has been performed. For example, if you launch Tweetbot from an app like Drafts, you can tell Tweetbot to return to Drafts once the tweet has been posted. What Chrome does that is so clever is it uses this parameter to give the browser a back button to return to the app it was launched from. So, if you open a link in Chrome from Tweetbot or a mail client like Mailbox, you'll get a back button in the browser to return to that app (it'll even close that now unused window). This ends up being a much nicer and quicker flow than tapping on the tabs manager, closing the tab, double-tapping the home button, switching apps, etc.

This is by far my single favorite thing about Chrome for iOS. I like it so much, in fact, that although I've switched back to Safari on OS X1, I've stuck with Chrome on iOS. I even champion the inclusion of this feature with app developers after I notice they've added Chrome support, but not support for x-success. It's that important to me.

However, not using the same browser across OS X and iOS is annoying enough that I notice it on a daily basis. Wouldn't it be great if Safari supported Chrome's back button behavior? It sure would. However, Apple's laissez faire attitude towards inter-app communication keeps me from holding my breath on this front. Therefore, I was truly excited when I saw this post by the father of x-callback-url himself, Greg Pierce, wherein he launches a simple HTML page in Safari and uses JavaScript to add x-success links to the page on his own. Woah, awesome!

However, Greg's technique depends on loading a full-screen iframe on the page and overlaying a back button on top to trigger the x-success url. That gets the job done, but I really prefer how Chrome handles this: make the last page jump to the previous app. I brainstormed for a bit and figured I could probably replicate Chrome's behavior's using Greg's idea, and I was right: was born.

The Anatomy of an URL

Here's how expects URLs:
    &x-source={{Source Friendly Name}}


The URL scheme used by is very similar to Greg's. Instead of directly opening a URL in Safari, you link to and pass in a few parameters:

  1. url: This is the url of the page you actually want to visit in Safari.

  2. x-success: Where the rubber meets the road, this is the URL you want to load when the user taps on the back button (usualy an app's URL scheme, but I guess it could be a normal HTTP URL too if you really wanted).

  3. x-source (Optional): The "friendly" name of the app you'll be going back to. This is displayed in your browser history.

Overall, it's very close to Greg's original format, with one major difference: the use of a hash (#) character after the base URL instead of a question mark. The reason for this is, unlike in Chrome, we can't automatically close the window when jumping back to the x-success app. Therefore, if we submitted all the parameters using normal query strings, we could potentially end up with a Safari browser littered with empty pages that were never closed. However, hash characters are not considered part of the actual URL in a browser (it doesn't even get sent to the backend server). Therefore, Safari will think all urls are the same and will just re-use the same tab over and over again, meaning we'll only have up to 1 tab open at a time. Not perfect, but a decent work-around to this limitation.

So there you have it, we now have x-success support in Safari, and it works pretty damn well if you ask me! Go ahead, load up your iOS device and try it out. If you have Tweetbot, view this tweet in Tweetbot, open the link in Safari, and then tap the back button to instantly be dropped back into Tweetbot. MAGICAL.

But Wait, There's Bad News

Wait a minute, this all sounds like it's working great! How can there be bad news?!

Well, the world isn't all sunshine and rainbows. Unfortunately, forcing all URLs to open via another URL brings with it a host of issues. First, there's app support. To get this working in an app like Tweetbot, Tapbots would have to make tapping on a URL in their app open up and submit the right parameters. Second, while integration is easy enough, what happens if the site goes away? or gets overloaded with traffic? or I become evil and decide to start serving ads to everyone to make some $$$? Do all URLs in Tweetbot suddenly break?

These are valid concerns, and would certainly get me to think twice about integrating the scheme if it were my app. So, for now, this lives as an experiment and proof of concept. You can use this scheme in apps that allow you to define your own URL schemes for launching, such as Greg's own Drafts app or Contrast's Launch Center Pro. But any support or use beyond that looks unlikely at best.

Regardless, I think this is pretty cool, and I at least hope any attention this hack gets is either useful to your specific situation, or gets Apple thinking about integrating this kind of communication in their own apps in the future. If you have any questions, concerns, or suggestions, feel free to leave an Issue on the GitHub project page.

  1. Safari on Mavericks is ludicrously smooth and fast.