Skip to content
Jeffrey Starke edited this page Jul 8, 2020 · 42 revisions

Table of Contents

Matching urls

module.exports = {
  defaultBrowser: "Google Chrome",
  rewrite: [
    {
      match: *MATCHER*,
      url: "http://example.com",
    },
  ],
  handlers: [
    {
      match: *MATCHER*,
      browser: "Safari",
    },
  ],
};

Examples

A handler or url rewrite always needs a matcher to match the incoming url. There are a couple of different ways to match a url:

  // Only matches that exact url
  match: "http://example.com/path?query" 
  // Matches anything the Regular Expression matches
  match: /^https?:\/\/example\.com/.*$/ 
  // A function that accepts some arguments. 
  match: ({ url }) => url.host === "example.com"
  // Or, an array with any combination of the above
  match: ["https://example.com", /^http:\/\/example.(org|com)\/.*/]

The full parameter description for functions is available here

Selecting a browser

module.exports = {
  defaultBrowser: *BROWSER*,
  handlers: [
    {
      match: ({ url }) => url.host.endsWith("example.org"),
      browser: *BROWSER*,
    },
  ],
};

1. Browser (or app) as a string:

  // Name
  browser: "Google Chrome" 
  // Bundle identifier (useful when the app name isn't unique)
  browser: "com.google.Chrome" 
  // Path to application. Useful when both name and bundle id aren't unique
  browser: "/Applications/Firefox.app" 

Finicky will try detect automatically if what was entered was a name, a bundle id or a path name. If you don't know what bundle id to use, see this wiki entry

2. You can define more options with a browser object.

If you want to force the string type you can supply it in a browser object:

```js
  browser: {
    name: "Google Chrome",
    type: "appName" // Force name type. "appName", "bundleId" or "appPath",
    openInBackground: true // or false, force opening the browser in the background
  }

3. A browser function that returns either a browser string or object

  browser: ({ url }) => url.host === "example.com" ? "Google Chrome" : "Firefox"
  browser: ({ urlString }) => {
    name: "Google Chrome",
    openInBackground: urlString.includes("facebook")
  }

Rewriting urls

If you want to change the incoming url in any way, you can do that in a couple of different ways.

module.exports = {
  defaultBrowser: "Safari",
  rewrite: [
    {
      match: ({ url }) => url.host.endsWith("example.org"),
      url: *URL*,
    },
  ],
};

The url property can either be:

  // A string for the a completely new url
  url: "http://example.com?something=else"
  // A URL Object
  url: {
    "host": "example.com",
    "protocol": "https"
  }
  // A function that returns either a url string or a url object
  url: ({ url }) => {
    return {
      ...url,
      protocol: "https"
    }
  }

Options

module.exports = {
  defaultBrowser: "Google Chrome",
  options: {
    // Hide the finicky icon from the top bar. Default: false
    hideIcon: false, 
    // Check for update on startup. Default: true
    checkForUpdate: true,
    // Override the internal list of url shortener services 
    urlShorteners: ["t.co", "spoti.fi"]
  },
};

The default list of short url providers can be found here. Finicky uses this list to resolve urls to the intended destination before running them through the rule system.

Example configuration

module.exports = {
  defaultBrowser: "Google Chrome",
  options: {
    // Hide the finicky icon from the top bar
    hideIcon: true
  },
  handlers: [
    {
      // Open any link clicked in Slack in Safari
      match: ({ sourceBundleIdentifier }) =>
        sourceBundleIdentifier === "com.tinyspeck.slackmacgap",
      browser: "Safari"
    },
    {
      // You can get the path of the process that triggered Finicky (EXPERIMENTAL)
      match: ({ sourceProcessPath }) =>
        sourceProcessPath && sourceProcessPath.startsWith("/Applications/Slack.app"),
      browser: "Firefox"
    },
    {
      match: ["http://zombo.com"],
      browser: {
        name: "Google Chrome Canary",
        // Force opening the link in the background
        openInBackground: true
      }
    },
    {
      match: finicky.matchHostnames(["example.com"]),
      // Opens the first running browsers in the list. If none are running, the first one will be started.
      browser: ["Google Chrome", "Safari", "Firefox"]
    },
    {
      match: ["http://example.com"],
      // Don't open any browser for this url, effectively blocking it
      browser: null
    },
    {
      // Open links in Safari when the option key is pressed
      // Valid keys are: shift, option, command, control, capsLock, and function.
      // Please note that control usually opens a tooltip menu instead of visiting a link
      match: ({ keys }) => keys.option,
      browser: "Safari"
    }
  ]
};

API specification

finicky.log(message: string)

Logs a string to the finicky console

module.exports = {
  defaultBrowser: "Google Chrome",
  handlers: [{
    match: ({ url, urlString }) => {
      finicky.log("Recieved url " + urlString);
      return url.host === "apple.com";
    }
    browser: "Safari"
  }]
}

finicky.notify(title: string, subtitle: string)

Display a notification

module.exports = {
  defaultBrowser: "Google Chrome",
  handlers: [{
    match: ({ url, urlString }) => {
      finicky.notify("Recieved url", urlString);
      return url.host === "apple.com";
    }
    browser: "Safari"
  }]
}

finicky.getBattery() => { isCharging: bool, isPluggedIn: bool, chargePercentage: number }

Get the battery status.

module.exports = {
  // Use Safari as default when battery is low
  defaultBrowser: () => finicky.getBattery().chargePercentage < 50 ? "Safari" : "Google Chrome",
}

finicky.matchHostnames(matchers: string | RegExp | (string | RegExp)[]) => bool

Utility function to make it easier to match on the domain part

module.exports = {
  defaultBrowser: "Google Chrome",
  handlers: [{
    match: finicky.matchHostnames(["apple.com", /example\.(com|org|net)/]),
    browser: "Safari"
  }]
}
Clone this wiki locally