Safari - Find a Specific Tab and Open It - If it Doesn't Exist then Open a New Tab

Hello!

I would like to create a keybinding that when hit:

  • Searches Safari for a specific URL (ie https://3.basecamp.com/)
  • Opens the tab if found
  • If not, opens a new URL with specific URL

It's well beyond my skill level. I searched and found similar workflows but they were slightly different, sorry if this is a repeated question.

Thanks!

This macro from @JMichaelTX has worked for me.

Just noticed that the @JMichaelTX macro does not address your third bullet.

Assuming you want to check for the same URL every time, here's a simple AppleScript -- just change the URL in the first line to the one you want to check for. This (ab)uses the behaviour of the "of every window" command returning a list ordered by the index of the Safari window -- know where something is in the list and you know which window to pop to the front -- and that the "new document" command makes a new frontmost window. If you have multiple windows/tabs that match it will pop the first it comes to (again, in window index order).

There's zero error checking because I've never seen it error! YMMV...

property wantedURL : "https://www.bbc.co.uk"

tell application "Safari"
	activate
	set theURLs to (get URL of every tab of every window)
	repeat with x from 1 to length of theURLs
		set tmp to item x of theURLs
		repeat with y from 1 to length of tmp
			if item y of tmp contains wantedURL then
				set the index of window x to 1
				tell window 1
					if index of current tab is not y then set current tab to tab y
					return 0
				end tell
			end if
		end repeat
	end repeat
	--if we get here the tab wasn't open so...
	make new document with properties {URL:wantedURL}
end tell

Put that into your KM macro as an "Execute an AppleScript" action, change the "wantedURL" property to the one you want, and you should be good to go. And it could easily be extended to eg accept a variable from KM as the "wantedURL" term so you could use it for more than one site.

Thanks, everyone!

@JMichaelTX and @Nige_S - how can I get that third condition, if the macro or script fails (i.e. can't find the URL), then open the URL?

Also, is there a wildcard I can throw on the end of the URL so that it finds any variation after the first part?

Thanks!

It already does both these things.

If you look at the code, if it finds any tab whose URL contains "wantedURL" it brings that tab to the front. We're playing on the fact that any tabs have open won't have "wantedURL" anywhere except at the start of their URL string -- even a Google search for that URL would have the "://" URL encoded, so wouldn't be returned -- so "contains" is actually "starts with".

So it might, perhaps, be more lax than you actually want! Make it as precise as you can to minimise false positives -- eg if it's actually the BBC News pages you want, make it "Home - BBC News".

You'll also see that if it finds the page and brings it to the front it will also execute the "return 0" statement (last line of the most indented block). The effect of that is that the script exits at that point and nothing after that part is executed. The corollary is that if "wantedURL" isn't found then that bit is skipped and the script runs all the way to the end, where the penultimate line makes a new window and loads the "wantedURL". Again, we're (ab)using the fact that a new Safari window is always at the front so we don't need to move it to frontmost.

Hope that explains things a bit better.

This is absolutely amazing! Thank you so much.

One question, if this is not possible no worries.

If it does not find the URL it opens it but it opens it in a new window, even if I have an existing Safari window open. Is there any way to open it in the active window vs a net new one?

Thanks!

Replacing the current page, or making a new tab in the current window? Replace the penultimate line:

make new document with properties {URL:wantedURL}

with either

set URL of current tab of window 1 to wantedURL

...for the first, or

set current tab of window 1 to (make new tab in window 1 with properties {URL:wantedURL})

...for the second.

The first is pretty self explanatory -- "window 1" is the active window, "current tab" is what it says on the tin (even when there's only one tab-that-doesn't-look-like-a-tab in a window), and you're setting its URL.

In the second, the bit in parentheses is executed first and makes a new tab with the wanted URL. That returns a reference to the newly-created tab, making the first part of the line "make the current tab the one we've just created", ie activating the front window's newly created tab.

That second one did the trick, thank you @Nige_S!!!

@Nige_S -

Sorry, one more snag with:
set current tab of window 1 to (make new tab in window 1 with properties {URL:wantedURL})

If I have a window open already it's great, but it does not fire and open a new window if one was not open already.

Try replacing

set current tab of window 1 to (make new tab in window 1 with properties {URL:wantedURL})

with

if count of windows ≠ 0 then
    set current tab of window 1 to (make new tab in window 1 with properties {URL:wantedURL})
else
    make new document with properties {URL:wantedURL}
end if

But really, if you frequently find yourself switching to Safari and it doesn't have any windows open, you'd be better off short-circuiting the script by having the check first:

property wantedURL : "https://www.bbc.co.uk"

tell application "Safari"
	activate
	if count of windows = 0 then
		make new document with properties {URL:wantedURL}
	else
		set theURLs to (get URL of every tab of every window)
		repeat with x from 1 to length of theURLs
			set tmp to item x of theURLs
			repeat with y from 1 to length of tmp
				if item y of tmp contains wantedURL then
					set the index of window x to 1
					tell window 1
						if index of current tab is not y then set current tab to tab y
						return 0
					end tell
				end if
			end repeat
		end repeat
		--if we get here the tab wasn't open so...
		set current tab of window 1 to (make new tab in window 1 with properties {URL:wantedURL})
	end if
end tell

This works!

Can I buy you a coffee! Seriously, thank you for the help :pray:.

@Nige_S - this script has been so helpful. I use it 20 times daily to switch to the right web apps.

I was debating moving to Arc (I've got an invite if you want one :wink:) and was wondering if I could simply change the "tell application" from Safari to Arc? It's a chromium-based browser.

"Chromium-based" does not necessarily mean "supports AppleScript" -- you'll have to suck it and see.

Nyet...

Even if Arc supports AppleScript (as it should), the syntax between Chrome and Safari is different.

There will be a little bit of overlap, but many functions will have slightly (or significantly) different syntax.

What would be the syntax if it was Chrome?

My assumption and what I would test is that but replace "Chrome" with Arc.

Don't assume – test...

Make damn sure Arc is scriptable before doing anything.

If it is then you can go-to-town.

Here's a place to start:

Checking Whether a Given URL is Already Open in Google Chrome Tabs - #2 by peternlewis

There are a number of other macros on the forum that do this kind of thing.

Here's one:

Google Chrome – How to Bring an Existing GMail Tab to the Front - #11 by ccstone