# psl (Public Suffix List)
[](https://github.com/lupomontero/psl/actions/workflows/node.js.yml)
`psl` is a `JavaScript` domain name parser based on the
[Public Suffix List](https://publicsuffix.org/).
This implementation is tested against the
[test data hosted by Mozilla](http://mxr.mozilla.org/mozilla-central/source/netwerk/test/unit/data/test_psl.txt?raw=1)
and kindly provided by [Comodo](https://www.comodo.com/).
Cross browser testing provided by
[](https://www.browserstack.com/)
## What is the Public Suffix List?
The Public Suffix List is a cross-vendor initiative to provide an accurate list
of domain name suffixes.
The Public Suffix List is an initiative of the Mozilla Project, but is
maintained as a community resource. It is available for use in any software,
but was originally created to meet the needs of browser manufacturers.
A "public suffix" is one under which Internet users can directly register names.
Some examples of public suffixes are ".com", ".co.uk" and "pvt.k12.wy.us". The
Public Suffix List is a list of all known public suffixes.
Source: http://publicsuffix.org
## Installation
### Node.js
```sh
npm install --save psl
```
### Browser
Download [psl.min.js](https://raw.githubusercontent.com/lupomontero/psl/master/dist/psl.min.js)
and include it in a script tag.
```html
```
This script is browserified and wrapped in a [umd](https://github.com/umdjs/umd)
wrapper so you should be able to use it standalone or together with a module
loader.
## API
### `psl.parse(domain)`
Parse domain based on Public Suffix List. Returns an `Object` with the following
properties:
* `tld`: Top level domain (this is the _public suffix_).
* `sld`: Second level domain (the first private part of the domain name).
* `domain`: The domain name is the `sld` + `tld`.
* `subdomain`: Optional parts left of the domain.
#### Example:
```js
var psl = require('psl');
// Parse domain without subdomain
var parsed = psl.parse('google.com');
console.log(parsed.tld); // 'com'
console.log(parsed.sld); // 'google'
console.log(parsed.domain); // 'google.com'
console.log(parsed.subdomain); // null
// Parse domain with subdomain
var parsed = psl.parse('www.google.com');
console.log(parsed.tld); // 'com'
console.log(parsed.sld); // 'google'
console.log(parsed.domain); // 'google.com'
console.log(parsed.subdomain); // 'www'
// Parse domain with nested subdomains
var parsed = psl.parse('a.b.c.d.foo.com');
console.log(parsed.tld); // 'com'
console.log(parsed.sld); // 'foo'
console.log(parsed.domain); // 'foo.com'
console.log(parsed.subdomain); // 'a.b.c.d'
```
### `psl.get(domain)`
Get domain name, `sld` + `tld`. Returns `null` if not valid.
#### Example:
```js
var psl = require('psl');
// null input.
psl.get(null); // null
// Mixed case.
psl.get('COM'); // null
psl.get('example.COM'); // 'example.com'
psl.get('WwW.example.COM'); // 'example.com'
// Unlisted TLD.
psl.get('example'); // null
psl.get('example.example'); // 'example.example'
psl.get('b.example.example'); // 'example.example'
psl.get('a.b.example.example'); // 'example.example'
// TLD with only 1 rule.
psl.get('biz'); // null
psl.get('domain.biz'); // 'domain.biz'
psl.get('b.domain.biz'); // 'domain.biz'
psl.get('a.b.domain.biz'); // 'domain.biz'
// TLD with some 2-level rules.
psl.get('uk.com'); // null);
psl.get('example.uk.com'); // 'example.uk.com');
psl.get('b.example.uk.com'); // 'example.uk.com');
// More complex TLD.
psl.get('c.kobe.jp'); // null
psl.get('b.c.kobe.jp'); // 'b.c.kobe.jp'
psl.get('a.b.c.kobe.jp'); // 'b.c.kobe.jp'
psl.get('city.kobe.jp'); // 'city.kobe.jp'
psl.get('www.city.kobe.jp'); // 'city.kobe.jp'
// IDN labels.
psl.get('食狮.com.cn'); // '食狮.com.cn'
psl.get('食狮.公司.cn'); // '食狮.公司.cn'
psl.get('www.食狮.公司.cn'); // '食狮.公司.cn'
// Same as above, but punycoded.
psl.get('xn--85x722f.com.cn'); // 'xn--85x722f.com.cn'
psl.get('xn--85x722f.xn--55qx5d.cn'); // 'xn--85x722f.xn--55qx5d.cn'
psl.get('www.xn--85x722f.xn--55qx5d.cn'); // 'xn--85x722f.xn--55qx5d.cn'
```
### `psl.isValid(domain)`
Check whether a domain has a valid Public Suffix. Returns a `Boolean` indicating
whether the domain has a valid Public Suffix.
#### Example
```js
var psl = require('psl');
psl.isValid('google.com'); // true
psl.isValid('www.google.com'); // true
psl.isValid('x.yz'); // false
```
## Testing and Building
Test are written using [`mocha`](https://mochajs.org/) and can be
run in two different environments: `node` and `phantomjs`.
```sh
# This will run `eslint`, `mocha` and `karma`.
npm test
# Individual test environments
# Run tests in node only.
./node_modules/.bin/mocha test
# Run tests in phantomjs only.
./node_modules/.bin/karma start ./karma.conf.js --single-run
# Build data (parse raw list) and create dist files
npm run build
```
Feel free to fork if you see possible improvements!
## Acknowledgements
* Mozilla Foundation's [Public Suffix List](https://publicsuffix.org/)
* Thanks to Rob Stradling of [Comodo](https://www.comodo.com/) for providing
test data.
* Inspired by [weppos/publicsuffix-ruby](https://github.com/weppos/publicsuffix-ruby)
## License
The MIT License (MIT)
Copyright (c) 2017 Lupo Montero