[{"id":"content:1.guide:1.getting-started:0.index.md","path":"/guide/getting-started","dir":"guide","title":"Unlighthouse CLI","description":"Using the CLI is the quickest way to get familiar with Unlighthouse and is recommended for new users.","keywords":["Setup","Integrations and CI","Getting Help"],"body":" Unlighthouse CLI Using the CLI is the quickest way to get familiar with Unlighthouse and is recommended for new users. Setup Requirements: Node 14.x or higher, Node 16.x recommended. Using npx: npx unlighthouse --site < your-sit e >\n # OR pnpm dlx unlighthouse --site By default Unlighthouse will attempt to use your system Chrome / Chromium install.\nIf these are missing, a Chromium binary will be installed on your system. To learn more about the CLI and the arguments, head over to CLI Integration . Windows WSL If you're using Windows Subsystem for Linux and run into issues, see Solving Common Errors . Integrations and CI See the integrations page for more information. Getting Help If you have questions or need help, reach out to the community on the Discord . .ct-902167{color:#FFCB6B;}\n.light .ct-902167{color:#E2931D;}\n.dark .ct-037119{color:#A6ACCD;}\n.ct-037119{color:#EEFFFF;}\n.light .ct-037119{color:#90A4AE;}\n.ct-083593{color:#C3E88D;}\n.light .ct-083593{color:#91B859;}\n.ct-542793{color:#89DDFF;}\n.light .ct-542793{color:#39ADB5;}\n.dark .ct-649848{color:#676E95;font-style:italic;}\n.ct-649848{color:#546E7A;font-style:italic;}\n.light .ct-649848{color:#90A4AE;font-style:italic;}"},{"id":"content:1.guide:1.getting-started:1.integrations.md","path":"/guide/getting-started/integrations","dir":"getting-started","title":"Integrations","description":"","keywords":["Command Line","Build tools / Frameworks","Getting Help"],"body":" Integrations Command Line Provider Use Case CLI Scan a production site such as unlighthouse.dev . You can manually provide a project mapping for routes definitions . CI Run scans on sites based on automation events, i.e releasing and make assertions on scores . Can also be used to generate report sites such as inspect.unlighthouse.dev . Build tools / Frameworks These integrations are now deprecated and will be removed in the v1 major release.\nRead more about integration deprecations . Provider Features Nuxt.js Hot Module Reloading Automatic Route Discovery Vite Hot Module Reloading Automatic Route Discovery webpack Hot Module Reloading Getting Help If you have questions or need help, reach out to the community on the Discord ."},{"id":"content:1.guide:1.getting-started:how-it-works.md","path":"/guide/getting-started/how-it-works","dir":"getting-started","title":"How it works","description":"Unlighthouse has multiple steps, aimed at only running logic when it's needed.","keywords":["1. Instantiation","2. Server Context Provided","3. Start","3. Using the client"],"body":" How it works Unlighthouse has multiple steps, aimed at only running logic when it's needed. The core logic is as follows 1. Instantiation Configuration is loaded from unlighthouse.config.ts or a custom configFile . const unlighthouse = await createUnlighthouse (config) Worker A new puppeteer-cluster is created. 2. Server Context Provided Once the context is provided for which site is being scanned and server details. // create a server to serve the client from\n const { server , app } = await createServer ()\n await unlighthouse . setServerContext ( { url : server . url , server : server . server , app } ) API An unrouted API instance is created. Client Vite client is copied from the node_modules and is injected with static\nconfiguration for the scan 3. Start For integrations, Unlighthouse will only start when accessed. Otherwise, Unlighthouse is started straight away. hooks . hookOnce ( ' visited-client ' , () => {\n unlighthouse . start ()\n } ) Context Discovery of the route definitions is attempted. A virtual router for the route\ndefinitions is created. Attempt to read the robots.txt to disocver the sitemap and excluded routes. With the sitemap.xml, we collect the list of URLs to work with, if no sitemap is discovered, the home page will be\nscanned. Worker For each URL: perform a GET and extract HTML payload for basic SEO data and discover new internal links In a new thread, perform the lighthouse scan, the HTML and JSON payload of the report will be saved to the filesystem Client Broadcasting setup on worker events. 3. Using the client API The unrouted API instance routes requests to the worker to perform actions.\nStatic files such as the full-page screenshot and lighthouse HTML report are served. .ct-366012{color:#C792EA;}\n.light .ct-366012{color:#9C3EDA;}\n.dark .ct-037119{color:#A6ACCD;}\n.ct-037119{color:#EEFFFF;}\n.light .ct-037119{color:#90A4AE;}\n.ct-542793{color:#89DDFF;}\n.light .ct-542793{color:#39ADB5;}\n.ct-398028{color:#89DDFF;font-style:italic;}\n.light .ct-398028{color:#39ADB5;font-style:italic;}\n.ct-021512{color:#82AAFF;}\n.light .ct-021512{color:#6182B8;}\n.dark .ct-649848{color:#676E95;font-style:italic;}\n.ct-649848{color:#546E7A;font-style:italic;}\n.light .ct-649848{color:#90A4AE;font-style:italic;}\n.ct-821147{color:#F07178;}\n.light .ct-821147{color:#E53935;}\n.ct-083593{color:#C3E88D;}\n.light .ct-083593{color:#91B859;}"},{"id":"content:1.guide:guides:0.config.md","path":"/guide/guides/config","dir":"guides","title":"Configuration","description":"Each integration comes with a way to configure Unlighthouse inline;\nhowever, you may want to create a separate configuration file when dealing with complex sites.","keywords":["Configuration file","Example"],"body":" Configuration Each integration comes with a way to configure Unlighthouse inline;\nhowever, you may want to create a separate configuration file when dealing with complex sites. Configuration file By default, a unlighthouse.config.ts file within the root (or cwd ) directory will be read.\nYou can change the name of the configuration file with the configFile option, or --config flag for the CLI. Local dependency - with Typescript When you load Unlighthouse into your project as a dev dependency and you're using Typescript, you can make use of proper\nconfiguration types. /// < reference types = \" unlighthouse \" />\n import { defineConfig } from ' unlighthouse '\n \n export default defineConfig ( {\n // examplebtn-basic\n site : ' unlighthouse.dev ' ,\n scanner : {\n exclude : [ ' /private-zone/* ' ]\n },\n debug : true ,\n } ) Global dependency You can still provide a configuration file when using Unlighthouse globally, however, you won't be able to make use of\nthe types or defineConfig function, instead you'll need to export a plain object. export default {\n // example\n site : ' unlighthouse.dev ' ,\n scanner : {\n exclude : [ ' /private-zone/* ' ]\n },\n debug : true ,\n } See the list of config options in the Config Reference . Example export default {\n site : ' harlanzw.com ' ,\n scanner : {\n // exclude specific routes\n exclude : [\n ' /.*?pdf ' ,\n ' .*/amp ' ,\n ' en-* ' ,\n ] ,\n // run lighthouse for each URL 3 times\n samples : 3 ,\n // use desktop to scan\n device : ' desktop ' ,\n // enable the throttling mode\n throttle : true ,\n },\n debug : true ,\n } .dark .ct-649848{color:#676E95;font-style:italic;}\n.ct-649848{color:#546E7A;font-style:italic;}\n.light .ct-649848{color:#90A4AE;font-style:italic;}\n.ct-398028{color:#89DDFF;font-style:italic;}\n.light .ct-398028{color:#39ADB5;font-style:italic;}\n.ct-965912{color:#F07178;font-style:italic;}\n.light .ct-965912{color:#E53935;font-style:italic;}\n.ct-221247{color:#C792EA;font-style:italic;}\n.light .ct-221247{color:#9C3EDA;font-style:italic;}\n.ct-228358{color:#C3E88D;font-style:italic;}\n.light .ct-228358{color:#91B859;font-style:italic;}\n.dark .ct-037119{color:#A6ACCD;}\n.ct-037119{color:#EEFFFF;}\n.light .ct-037119{color:#90A4AE;}\n.ct-542793{color:#89DDFF;}\n.light .ct-542793{color:#39ADB5;}\n.ct-821147{color:#F07178;}\n.light .ct-821147{color:#E53935;}\n.ct-083593{color:#C3E88D;}\n.light .ct-083593{color:#91B859;}\n.ct-021512{color:#82AAFF;}\n.light .ct-021512{color:#6182B8;}\n.ct-358248{color:#FF9CAC;}\n.light .ct-358248{color:#FF5370;}\n.ct-053683{color:#F78C6C;}\n.light .ct-053683{color:#F76D47;}"},{"id":"content:1.guide:guides:authentication.md","path":"/guide/guides/authentication","dir":"guides","title":"Authentication","description":"Unlighthouse is built to support scanning sites that require authentication.","keywords":["Basic Authentication","Cookie Authentication","Custom Headers Authentication","Query Params","Local Storage","Programmatic Usage","Troubleshooting"],"body":" Authentication Unlighthouse is built to support scanning sites that require authentication. Basic Authentication To use basic authentication, provide the auth option in your configuration file: // unlighthouse.config.ts\n export default {\n auth : {\n username : ' username ' ,\n password : ' password ' ,\n },\n } Alternatively, you can provide the --auth flag to the CLI. unlighthouse --site < your-sit e > --auth username:password Cookie Authentication If you can authenticate your session using cookies, use the cookies option in your configuration file: // unlighthouse.config.ts\n export default {\n cookies : [\n {\n name : ' my-jwt-token ' ,\n value : ' ' ,\n // optional extras\n domain : ' your-site.com ' ,\n path : ' / ' ,\n httpOnly : false ,\n secure : false ,\n sameSite : ' Lax ' ,\n },\n ] ,\n } Alternatively, you can provide the --cookies flag to the CLI. unlighthouse --site < your-sit e > --cookies \" my-jwt-token= \" You can provide multiple cookies by separating them with a ; . unlighthouse --site < your-sit e > --cookies my-jwt-token= < toke n >; my-other-cookie=value Custom Headers Authentication If providing cookies or basic auth is not enough, you can provide custom headers to be sent with each request. To use custom headers, provide the extraHeaders option in your configuration file: // unlighthouse.config.ts\n export default {\n extraHeaders : {\n ' x-custom-auth ' : ' > ' ,\n },\n } Alternatively, you can provide the --extra-headers flag to the CLI. unlighthouse --site < your-sit e > --extra-headers x-custom-header:custom-value You can provide multiple headers by separating them with a , . unlighthouse --site < your-sit e > --extra-headers x-custom-header:custom-value,x-other-header:other-value Query Params If you can configure your authentication using query params,\nthen you can provide them using the defaultQueryParams option in your configuration file: // unlighthouse.config.ts\n export default {\n defaultQueryParams : {\n auth : ' '\n }\n } Alternatively, you can provide the --default-query-params flag to the CLI. unlighthouse --site < your-sit e > --default-query-params auth= < toke n > ,foo=bar Local Storage If you can configure your authentication using local storage,\nthen you can provide them using the localStorage option in your configuration file: // unlighthouse.config.ts\n export default {\n localStorage : {\n auth : ' '\n }\n } Programmatic Usage You can also use control Puppeteer programmatically before the page is scanned using a config file.\nThis is\nmore experimental, and you may run into issues. You can see an example here: // unlighthouse.config.ts\n export default {\n hooks : {\n async authenticate ( page ) {\n // login to the page\n await page . goto ( ' https://example.com/login ' )\n const emailInput = await page . $ ( ' input[type=\"email\"] ' )\n await emailInput . type ( ' admin@example.com ' )\n const passwordInput = await page . $ ( ' input[type=\"password\"] ' )\n await passwordInput . type ( ' password ' )\n await Promise . all ([\n page . $eval ( ' .login-form ' , form => form . submit ()) ,\n page . waitForNavigation () ,\n ])\n },\n },\n } Troubleshooting If you're having trouble authenticating,\nyou can use the debug: true and headless: false ,\nflags to see what's happening. // unlighthouse.config.ts\n export default {\n debug: true ,\n // show the browser window\n puppeteerOptions: {\n headless: false ,\n } ,\n // only run a single scan at a time\n puppeteerClusterOptions: {\n maxConcurrency: 1 ,\n },\n } .dark .ct-649848{color:#676E95;font-style:italic;}\n.ct-649848{color:#546E7A;font-style:italic;}\n.light .ct-649848{color:#90A4AE;font-style:italic;}\n.ct-398028{color:#89DDFF;font-style:italic;}\n.light .ct-398028{color:#39ADB5;font-style:italic;}\n.dark .ct-037119{color:#A6ACCD;}\n.ct-037119{color:#EEFFFF;}\n.light .ct-037119{color:#90A4AE;}\n.ct-542793{color:#89DDFF;}\n.light .ct-542793{color:#39ADB5;}\n.ct-821147{color:#F07178;}\n.light .ct-821147{color:#E53935;}\n.ct-083593{color:#C3E88D;}\n.light .ct-083593{color:#91B859;}\n.ct-902167{color:#FFCB6B;}\n.light .ct-902167{color:#E2931D;}\n.ct-358248{color:#FF9CAC;}\n.light .ct-358248{color:#FF5370;}\n.ct-366012{color:#C792EA;}\n.light .ct-366012{color:#9C3EDA;}\n.dark .ct-785412{color:#A6ACCD;font-style:italic;}\n.ct-785412{color:#EEFFFF;font-style:italic;}\n.light .ct-785412{color:#90A4AE;font-style:italic;}\n.ct-021512{color:#82AAFF;}\n.light .ct-021512{color:#6182B8;}\n.ct-053683{color:#F78C6C;}\n.light .ct-053683{color:#F76D47;}"},{"id":"content:1.guide:guides:chrome-dependency.md","path":"/guide/guides/chrome-dependency","dir":"guides","title":"Chrome Dependency","description":"Unlighthouse aims to keep the installation size small, for this reason it depends natively on your locally installed\nChrome.","keywords":["Disabling system chrome","Customizing the fallback installer","Using your own chrome path"],"body":" Chrome Dependency Unlighthouse aims to keep the installation size small, for this reason it depends natively on your locally installed\nChrome. As a fallback, it will download a Chromium binary for you. Disabling system chrome You can disable the system chrome usage by providing chrome.useSystem: false . This will force the fallback installer to run. Customizing the fallback installer When Chrome can't be found on your system or if the chrome.useSystem: false flag is passed, then a fallback will be attempted. This fallback will download a chrome binary for your system and use that path. There are a number of options you can customize on this. chrome.useDownloadFallback - Disables the fallback installer chrome.downloadFallbackVersion - Which version of chromium to use (default 1095492 ) chrome.downloadFallbackCacheDir - Where the binary should be saved (default $home/.unlighthouse ) Using your own chrome path You can provide your own chrome path by setting puppeteerOptions.executablePath . export default {\n puppeteerOptions : {\n executablePath : ' /usr/bin/chrome '\n }\n } .ct-398028{color:#89DDFF;font-style:italic;}\n.light .ct-398028{color:#39ADB5;font-style:italic;}\n.dark .ct-037119{color:#A6ACCD;}\n.ct-037119{color:#EEFFFF;}\n.light .ct-037119{color:#90A4AE;}\n.ct-542793{color:#89DDFF;}\n.light .ct-542793{color:#39ADB5;}\n.ct-821147{color:#F07178;}\n.light .ct-821147{color:#E53935;}\n.ct-083593{color:#C3E88D;}\n.light .ct-083593{color:#91B859;}"},{"id":"content:1.guide:guides:common-errors.md","path":"/guide/guides/common-errors","dir":"guides","title":"Solving Common Errors","description":"These are common issues that pop up when working with Unlighthouse. This will be updated when new issues are found.","keywords":["connect ECONNREFUSED 127.0.0.1:"],"body":" Solving Common Errors These are common issues that pop up when working with Unlighthouse. This will be updated when new issues are found. As a first step, you should always make sure you're using the latest Unlighthouse version. connect ECONNREFUSED 127.0.0.1: Example Error: Unable to launch browser for worker, error message: connect ECONNREFUSED 127.0.0.1:51667 This error is thrown when Chromium is unable to launch. This happens when puppeteer is unable to connect to the browser.\nThis can be from a number of reasons: The environment is not configured correctly, likely when using Windows and WSL. You have a firewall or antivirus blocking Chrome or Chromium from launching or connecting to the required port. You are using an unsupported version of Chrome or Chromium. Windows and WSL Solution Install Puppeteer on WSL following the documentation . Install Chrome in WSL following the documentation . Other Environments You can try disabling the system Chrome, instead using the fallback. export default {\n chrome : {\n // forces the fallback to be used\n useSystem : false\n }\n } .ct-398028{color:#89DDFF;font-style:italic;}\n.light .ct-398028{color:#39ADB5;font-style:italic;}\n.dark .ct-037119{color:#A6ACCD;}\n.ct-037119{color:#EEFFFF;}\n.light .ct-037119{color:#90A4AE;}\n.ct-542793{color:#89DDFF;}\n.light .ct-542793{color:#39ADB5;}\n.ct-821147{color:#F07178;}\n.light .ct-821147{color:#E53935;}\n.dark .ct-649848{color:#676E95;font-style:italic;}\n.ct-649848{color:#546E7A;font-style:italic;}\n.light .ct-649848{color:#90A4AE;font-style:italic;}\n.ct-358248{color:#FF9CAC;}\n.light .ct-358248{color:#FF5370;}"},{"id":"content:1.guide:guides:device.md","path":"/guide/guides/device","dir":"guides","title":"Selecting Device","description":"Unlighthouse uses the lighthouse node module to perform scans.","keywords":["Alias: Switching between mobile and desktop","Change device dimensions","Alias: Enable/Disable Throttling"],"body":" Selecting Device Unlighthouse uses the lighthouse node module to perform scans. By default, Unlighthouse will uses the default lighthouse configuration, which emulates a mobile device. Unlighthouse\ndoes not throttle by default. The device dimensions details are: width : 375 height : 667 Config alises are provided to modify the emulated device behaviour. Alias: Switching between mobile and desktop By default, Unlighthouse will run the audit using an emulated mobile desktop. To change it to desktop: export default {\n scanner : {\n device : ' desktop ' ,\n }\n } To change it to mobile (default): export default {\n scanner : {\n device : ' mobile ' ,\n }\n } Note: This is an alias for setting the option yourself manually via lighthouseOptions . Change device dimensions Changing the device dimensions can be useful if you want to test content that is only shown as specific dimensions. export default {\n lighthouseOptions : {\n screenEmulation : {\n width : 1800 ,\n height : 1000 ,\n }\n }\n } Alias: Enable/Disable Throttling There are two types of throttling: CPU and network. Both are used in combination to emulate visitors to your site who\nhave poor internet connection and slow devices. Unlighthouse will by default, throttle request to production sites for a more accurate performance score. In development, it makes less sense to throttle as the network and CPU conditions for local development servers will\nskew the results. If you would like to modify the throttling for each environment you can do: export default {\n scanner : {\n throttle : true\n }\n } Note: throttle is an alias for modifying lighthouseOptions.throttlingMethod and lighthouseOptions.throttling . .ct-398028{color:#89DDFF;font-style:italic;}\n.light .ct-398028{color:#39ADB5;font-style:italic;}\n.dark .ct-037119{color:#A6ACCD;}\n.ct-037119{color:#EEFFFF;}\n.light .ct-037119{color:#90A4AE;}\n.ct-542793{color:#89DDFF;}\n.light .ct-542793{color:#39ADB5;}\n.ct-821147{color:#F07178;}\n.light .ct-821147{color:#E53935;}\n.ct-083593{color:#C3E88D;}\n.light .ct-083593{color:#91B859;}\n.ct-053683{color:#F78C6C;}\n.light .ct-053683{color:#F76D47;}\n.ct-358248{color:#FF9CAC;}\n.light .ct-358248{color:#FF5370;}"},{"id":"content:1.guide:guides:docker.md","path":"/guide/guides/docker","dir":"guides","title":"Docker and GitHub CI","description":"Using Unlighthouse in a Docker container is a great way to run it in a predictable CI environment.","keywords":["Unlighthouse Config","Docker File"],"body":" Docker and GitHub CI Using Unlighthouse in a Docker container is a great way to run it in a predictable CI environment. Support is experimental and provided by the community. An official docker image may be created in the future. It requires special configuration to the puppeteer instance. The running puppeteer in docker article is a great read. Unlighthouse Config It's recommended you only use the @unlighthouse/ci with Docker. Hosting the client does not have known support. You will need to remove the Chrome sandbox in a Docker environment, this will require using an unlighthouse.config.ts file. // unlighthouse.config.ts\n export default {\n puppeteerOptions : {\n args : [ ' --no-sandbox ' , ' --disable-setuid-sandbox ' ] ,\n },\n } If you're using the unlighthouse binary instead of the CI integration, then you will need to tell Unlighthouse not to use the server and close when\nthe reports are finished. // unlighthouse.config.ts\n export default {\n server : {\n open : false ,\n },\n hooks : {\n ' worker-finished ' : async () => {\n process . exit ( 0 )\n }\n }\n } Docker File Please see the following community repos: indykoning—Unlighthouse Docker .dark .ct-649848{color:#676E95;font-style:italic;}\n.ct-649848{color:#546E7A;font-style:italic;}\n.light .ct-649848{color:#90A4AE;font-style:italic;}\n.ct-398028{color:#89DDFF;font-style:italic;}\n.light .ct-398028{color:#39ADB5;font-style:italic;}\n.dark .ct-037119{color:#A6ACCD;}\n.ct-037119{color:#EEFFFF;}\n.light .ct-037119{color:#90A4AE;}\n.ct-542793{color:#89DDFF;}\n.light .ct-542793{color:#39ADB5;}\n.ct-821147{color:#F07178;}\n.light .ct-821147{color:#E53935;}\n.ct-083593{color:#C3E88D;}\n.light .ct-083593{color:#91B859;}\n.ct-358248{color:#FF9CAC;}\n.light .ct-358248{color:#FF5370;}\n.ct-366012{color:#C792EA;}\n.light .ct-366012{color:#9C3EDA;}\n.ct-021512{color:#82AAFF;}\n.light .ct-021512{color:#6182B8;}\n.ct-053683{color:#F78C6C;}\n.light .ct-053683{color:#F76D47;}"},{"id":"content:1.guide:guides:dynamic-sampling.md","path":"/guide/guides/dynamic-sampling","dir":"guides","title":"Dynamic Sampling","description":"","keywords":["Introduction","How it works","Usage"],"body":" Dynamic Sampling Introduction Dynamic sampling is a feature that allows you to automatically sample similar pages. This is useful for sites that have a lot of pages that are similar, such as a blog articles. It is enabled by default for most scans. How it works When dynamic sampling is enabled, it will group paths into chunks based on their path tree. For example, let's imagine we have a blog on our site and there are hundreds of blog posts. Scanning every blog post will\ntake a long time and may even break Unlighthouse. The path structure is /blog/{post} . Unlighthouse will turn this path structure into groups based on the /blog prefix. By default, it will sample\n5 paths starting with this prefix. A sample being a random selection of paths within this group. For example if we have the posts: /blog/post-a /blog/post-b /blog/post-c /blog/post-d /blog/post-e /blog/post-f /blog/post-g /blog/post-h /blog/post-i After sampling, we may end up with the random selection: /blog/post-c /blog/post-d /blog/post-e /blog/post-h /blog/post-i Usage It is configured using the scanner.dynamicSampling option. export default {\n scanner : {\n dynamicSampling : false , // or any number, default is 5\n }\n } Alternatively, you can disable it using the CLI --disable-dynamic-sampling . .ct-398028{color:#89DDFF;font-style:italic;}\n.light .ct-398028{color:#39ADB5;font-style:italic;}\n.dark .ct-037119{color:#A6ACCD;}\n.ct-037119{color:#EEFFFF;}\n.light .ct-037119{color:#90A4AE;}\n.ct-542793{color:#89DDFF;}\n.light .ct-542793{color:#39ADB5;}\n.ct-821147{color:#F07178;}\n.light .ct-821147{color:#E53935;}\n.ct-358248{color:#FF9CAC;}\n.light .ct-358248{color:#FF5370;}\n.dark .ct-649848{color:#676E95;font-style:italic;}\n.ct-649848{color:#546E7A;font-style:italic;}\n.light .ct-649848{color:#90A4AE;font-style:italic;}"},{"id":"content:1.guide:guides:generating-static-reports.md","path":"/guide/guides/generating-static-reports","dir":"guides","title":"Generating Static Reports","description":"","keywords":["Introduction","Using the CI mode","Static Reports","Interactive HTML Reports","CSV Reports","JSON Reports"],"body":" Generating Static Reports Introduction When you run Unlighthouse using npx unlighthouse , you're using the CLI mode. This mode generates and runs the interactive client. This is useful for quickly scanning your site and finding issues. However, you want to set up some automation around these reports. Creating reports that can be accessed through a static host. Unlighthouse ships with a CI mode which provides additional non-interactive features, one of them is generating static reports. Using the CI mode You'll need to manually install the CLI as a dependency to use unlighthouse-ci from the command line. npm install -g @unlighthouse/cli\n # yarn global add @unlighthouse/cli\n # pnpm install -g @unlighthouse/cli Please refer to the CI documentation for all features. Static Reports There are many types of reports you can generate. Interactive HTML Reports You can create static, self-hosted reports for your sites using the CI. This allows you to generate an always up-to-date version\nof how your site is performing overall. You can see an example of this here: https://inspect.unlighthouse.dev/ . You can generate a report like this by providing the --build-static flag. unlighthouse-ci --site < your-sit e > --build-static This will generate files in your outputPath ( .unlighthouse by default). You can upload the client directory to a static host from there. If you want to preview the static report you can run npx sirv-cli .unlighthouse/client Note: You will need to host your site using a web server. CloudFlare Pages Example You should create a CloudFlare Pages site using Direct Upload . You will use the wrangler CLI to upload the static report. You will need to init wrangler and configure it for your requirements. wrangler init You can then run the following command to generate the static report and upload it to CloudFlare Pages. unlighthouse-ci --site www.example.com --build-static && wrangler pages publish .unlighthouse GitHub Actions & Netlify Example This example is for GitHub Actions and deploys a static client build to Netlify. name: Assertions and static report\n \n on:\n workflow_dispatch:\n \n jobs:\n demo:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v2\n with:\n fetch-depth: 0\n \n - name: Install Dependencies\n run: npm add -g @unlighthouse/cli puppeteer\n \n - name: Unlighthouse assertions and client\n run: unlighthouse-ci --site --build-static\n \n - name: Deploy report to Netlify\n uses: nwtgck/actions-netlify@v1.2\n with:\n publish-dir: ./.unlighthouse\n production-branch: main\n production-deploy: true\n github-token: ${{ secrets.GITHUB_TOKEN }}\n deploy-message: New Release Deploy from GitHub Actions\n enable-pull-request-comment: false\n enable-commit-comment: true\n overwrites-pull-request-comment: true\n env:\n NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}\n NETLIFY_SITE_ID: ${{ secrets.NETLIFY_DEMO_SITE_ID }}\n timeout-minutes: 1 CSV Reports You can generate a CSV report by providing the --reporter csv or --reporter csvExpanded flag. unlighthouse-ci --site < your-sit e > --reporter csv Note: This report format is experimental and may change in the future. This will generate a report like the following ( csvExpanded sample): URL,Score,Performance,Accessibility,Best Practices,SEO,Largest Contentful Paint,Cumulative Layout Shift,FID,Blocking,Color Contrast,Headings,Image Alts,Link Names,Errors,Inspector Issues,Images Responsive,Image Aspect Ratio,Indexable,Tap Targets\n \"/\",93,72,100,100,100,3211.44,0,290.36,562.29,1,1,1,1,1,1,1,1,1,1\n \"/blog\",94,77,100,100,100,3911.7,0,205.57,260.03,1,1,1,1,1,1,1,1,1,1\n \"/blog/2023-april\",88,51,100,100,100,4925.84,0,311.24,797.95,1,1,1,1,1,1,1,1,1,1\n \"/blog/2023-february\",96,82,100,100,100,3207.98,0,209.96,302.01,1,1,1,1,1,1,1,1,1,1\n \"/blog/nuxt-3-migration-cheatsheet\",85,43,97,100,100,4373.88,0,1581.52,2820.75,0,1,1,1,1,1,1,1,1,1\n \"/blog/vue-automatic-component-imports\",93,74,97,100,100,1696.51,0,793.36,1314.27,0,1,1,1,1,1,1,1,1,1\n \"/blog/vue-use-head-v1\",82,30,97,100,100,8053.8,0,379.59,1127.99,0,1,1,1,1,1,1,1,1,1\n \"/projects\",92,66,100,100,100,3666.86,0,322.48,625.51,1,1,1,1,1,1,1,1,1,1\n \"/sponsors\",92,69,100,100,100,4438.15,0,362.62,408.63,1,1,1,1,1,1,1,1,1,1\n \"/talks\",98,90,100,100,100,864.86,0,390.93,427.94,1,1,1,1,1,1,1,1,1,1 JSON Reports You can generate a JSON report by providing the --reporter json or --reporter jsonExpanded flag. unlighthouse-ci --site < your-sit e > --reporter json Note: This report format is experimental and may change in the future. This will generate a report like the following ( json sample): [\n {\n \" path \" : \" / \" ,\n \" score \" : 0.97 ,\n \" performance \" : 0.87 ,\n \" accessibility \" : 1 ,\n \" best-practices \" : 1 ,\n \" seo \" : 1\n },\n {\n \" path \" : \" /blog \" ,\n \" score \" : 0.98 ,\n \" performance \" : 0.91 ,\n \" accessibility \" : 1 ,\n \" best-practices \" : 1 ,\n \" seo \" : 1\n },\n {\n \" path \" : \" /blog/2023-february \" ,\n \" score \" : 0.91 ,\n \" performance \" : 0.65 ,\n \" accessibility \" : 1 ,\n \" best-practices \" : 1 ,\n \" seo \" : 1\n },\n {\n \" path \" : \" /blog/modern-package-development \" ,\n \" score \" : 0.9 ,\n \" performance \" : 0.61 ,\n \" accessibility \" : 0.97 ,\n \" best-practices \" : 1 ,\n \" seo \" : 1\n },\n {\n \" path \" : \" /blog/scale-your-vue-components \" ,\n \" score \" : 0.87 ,\n \" performance \" : 0.51 ,\n \" accessibility \" : 0.97 ,\n \" best-practices \" : 1 ,\n \" seo \" : 1\n },\n {\n \" path \" : \" /blog/vue-automatic-component-imports \" ,\n \" score \" : 0.88 ,\n \" performance \" : 0.53 ,\n \" accessibility \" : 0.97 ,\n \" best-practices \" : 1 ,\n \" seo \" : 1\n },\n {\n \" path \" : \" /blog/vue-use-head-v1 \" ,\n \" score \" : 0.97 ,\n \" performance \" : 0.9 ,\n \" accessibility \" : 0.97 ,\n \" best-practices \" : 1 ,\n \" seo \" : 1\n },\n {\n \" path \" : \" /projects \" ,\n \" score \" : 0.94 ,\n \" performance \" : 0.77 ,\n \" accessibility \" : 1 ,\n \" best-practices \" : 1 ,\n \" seo \" : 1\n },\n {\n \" path \" : \" /sponsors \" ,\n \" score \" : 0.97 ,\n \" performance \" : 0.88 ,\n \" accessibility \" : 1 ,\n \" best-practices \" : 1 ,\n \" seo \" : 1\n },\n {\n \" path \" : \" /talks \" ,\n \" score \" : 0.94 ,\n \" performance \" : 0.74 ,\n \" accessibility \" : 1 ,\n \" best-practices \" : 1 ,\n \" seo \" : 1\n }\n ] .ct-902167{color:#FFCB6B;}\n.light .ct-902167{color:#E2931D;}\n.dark .ct-037119{color:#A6ACCD;}\n.ct-037119{color:#EEFFFF;}\n.light .ct-037119{color:#90A4AE;}\n.ct-083593{color:#C3E88D;}\n.light .ct-083593{color:#91B859;}\n.dark .ct-649848{color:#676E95;font-style:italic;}\n.ct-649848{color:#546E7A;font-style:italic;}\n.light .ct-649848{color:#90A4AE;font-style:italic;}\n.ct-542793{color:#89DDFF;}\n.light .ct-542793{color:#39ADB5;}\n.ct-366012{color:#C792EA;}\n.light .ct-366012{color:#9C3EDA;}\n.ct-053683{color:#F78C6C;}\n.light .ct-053683{color:#F76D47;}"},{"id":"content:1.guide:guides:lighthouse.md","path":"/guide/guides/lighthouse","dir":"guides","title":"Configuring Google Lighthouse","description":"Unlighthouse uses the lighthouse node module to perform scans.","keywords":["Lighthouse configuration","Aliases","Selecting Categories"],"body":" Configuring Google Lighthouse Unlighthouse uses the lighthouse node module to perform scans. Lighthouse configuration Any configuration available to lighthouse can be passed through on the lighthouseOptions key to change the behaviour\nof the reports. See lighthouse configuration for\ndetails. export default {\n lighthouseOptions : {\n throttlingMethod : ' devtools ' ,\n }\n } Aliases Unlighthouse aims to minimise and simplify configuration, where possible. For this reason, a number of configurations aliases are provided for your convenience. Switching device: mobile and desktop Toggle Throttling You can always configure lighthouse directly if you are comfortable with the configuration. Selecting Categories By default, Unlighthouse will scan the categories: 'performance', 'accessibility', 'best-practices', 'seo' . It can be useful to remove certain categories from being scanned to improve scan times. The Unlighthouse UI will adapt\nto any categories you select. Only Performance and PWA export default {\n lighthouseOptions : {\n onlyCategories : [ ' performance ' , ' pwa ' ] ,\n }\n } All Categories including PWA If you'd like to scan your app with the PWA category use: export default {\n lighthouseOptions : {\n onlyCategories : [ ' performance ' , ' best-practices ' , ' accessibility ' , ' seo ' , ' pwa ' ] ,\n }\n } .ct-398028{color:#89DDFF;font-style:italic;}\n.light .ct-398028{color:#39ADB5;font-style:italic;}\n.dark .ct-037119{color:#A6ACCD;}\n.ct-037119{color:#EEFFFF;}\n.light .ct-037119{color:#90A4AE;}\n.ct-542793{color:#89DDFF;}\n.light .ct-542793{color:#39ADB5;}\n.ct-821147{color:#F07178;}\n.light .ct-821147{color:#E53935;}\n.ct-083593{color:#C3E88D;}\n.light .ct-083593{color:#91B859;}"},{"id":"content:1.guide:guides:puppeteer.md","path":"/guide/guides/puppeteer","dir":"guides","title":"Configuring Puppeteer","description":"Unlighthouse uses puppeteer to run the lighthouse module.","keywords":["Puppeteer configuration","Hook into puppeteer navigation"],"body":" Configuring Puppeteer Unlighthouse uses puppeteer to run the lighthouse module. Puppeteer configuration You can configure puppeteer with the puppeteerOptions key, which will be passed to the puppeteer launch constructor. See puppeteer-launch-options for more information. For example, you could run without a headless browser. Although not recommended. export default {\n puppeteerOptions : {\n headless : false ,\n }\n } Hook into puppeteer navigation There may be instances where you need to hook into how the puppeteer instance is handling your pages. A hook is provided to do this. let token\n \n export default {\n hooks : {\n ' puppeteer:before-goto ' : async ( page ) => {\n if ( ! token )\n token = await generateToken ()\n \n // set authentication token when we load a new page\n await page . evaluateOnNewDocument ( ( token ) => {\n localStorage . clear ()\n localStorage . setItem ( ' token ' , token )\n }, token\n )\n },\n },\n } Delete an element export default {\n hooks : {\n ' puppeteer:before-goto ' : async ( page ) => {\n const deleteSelector = ' .VPNav '\n page . waitForNavigation () . then ( async () => {\n await page . waitForTimeout ( 1000 )\n await page . evaluate ( ( sel ) => {\n const elements = document . querySelectorAll ( sel )\n for ( let i = 0 ; i < elements . length ; i ++ )\n elements [ i ] . parentNode . removeChild ( elements [ i ])\n \n }, deleteSelector )\n } )\n }\n }\n } .ct-398028{color:#89DDFF;font-style:italic;}\n.light .ct-398028{color:#39ADB5;font-style:italic;}\n.dark .ct-037119{color:#A6ACCD;}\n.ct-037119{color:#EEFFFF;}\n.light .ct-037119{color:#90A4AE;}\n.ct-542793{color:#89DDFF;}\n.light .ct-542793{color:#39ADB5;}\n.ct-821147{color:#F07178;}\n.light .ct-821147{color:#E53935;}\n.ct-358248{color:#FF9CAC;}\n.light .ct-358248{color:#FF5370;}\n.ct-366012{color:#C792EA;}\n.light .ct-366012{color:#9C3EDA;}\n.dark .ct-785412{color:#A6ACCD;font-style:italic;}\n.ct-785412{color:#EEFFFF;font-style:italic;}\n.light .ct-785412{color:#90A4AE;font-style:italic;}\n.ct-021512{color:#82AAFF;}\n.light .ct-021512{color:#6182B8;}\n.dark .ct-649848{color:#676E95;font-style:italic;}\n.ct-649848{color:#546E7A;font-style:italic;}\n.light .ct-649848{color:#90A4AE;font-style:italic;}\n.ct-083593{color:#C3E88D;}\n.light .ct-083593{color:#91B859;}\n.ct-053683{color:#F78C6C;}\n.light .ct-053683{color:#F76D47;}"},{"id":"content:1.guide:guides:route-definitions.md","path":"/guide/guides/route-definitions","dir":"guides","title":"Route Definitions","description":"Route definitions are an optional feature of Unlighthouse.","keywords":["Pages directory","Custom sampling"],"body":" Route Definitions Route definitions are an optional feature of Unlighthouse. Providing them will give you more intelligent sampling and file hints. When you start Unlighthouse, it will try and map your page files to route definitions . Using Unlighthouse with the provided integrations, the route definitions should be discovered on their own.\nIf you have a custom setup or are using the CLI, you will need to manually set up the discovery. Pages directory By default, the pages/ dir is scanned for files with extensions .vue and .md , from the root directory. If your project has a different setup you can modify the configuration. export default {\n root : ' ./app ' ,\n discovery : {\n pagesDir : ' routes ' ,\n fileExtensions : [ ' jsx ' , ' md ' ] ,\n }\n } Custom sampling When you have URL patterns which don't use URL segments or the mapping is failing, it can be useful to map the sampling\nyourself. By using the customSampling option you map regex to a route definition. In the below example we will map any URL such as /q-search-query , /q-where-is-the-thing to a single route\ndefinition, , which allows the sampling to work. export default {\n scanner : {\n customSampling : {\n ' /q-(.*?) ' : {\n name : ' search-query '\n }\n }\n }\n } .ct-398028{color:#89DDFF;font-style:italic;}\n.light .ct-398028{color:#39ADB5;font-style:italic;}\n.dark .ct-037119{color:#A6ACCD;}\n.ct-037119{color:#EEFFFF;}\n.light .ct-037119{color:#90A4AE;}\n.ct-542793{color:#89DDFF;}\n.light .ct-542793{color:#39ADB5;}\n.ct-821147{color:#F07178;}\n.light .ct-821147{color:#E53935;}\n.ct-083593{color:#C3E88D;}\n.light .ct-083593{color:#91B859;}"},{"id":"content:1.guide:guides:url-discovery.md","path":"/guide/guides/url-discovery","dir":"guides","title":"Site Crawler","description":"Unlighthouse comes with multiple methods for URL discovery in the form of crawling.","keywords":["Robots.txt","Sitemap.xml","Crawler","Disable crawling","Manually Providing URLs"],"body":" Site Crawler Unlighthouse comes with multiple methods for URL discovery in the form of crawling. Add the specified site from --site or config Manually providing URLs via the --urls flag or urls on the provider. robotsTxt - Reading robots.txt, if it exists. Provides sitemap URLs and disallowed paths. sitemap - Reading sitemap.xml, if it exists crawler - Inspecting internal links Using provided static route definitions Robots.txt When a robots.txt is found, it will attempt to read the sitemap and disallowed paths. Disabling robots You may not want to use the robots.txt in all occasions. For example if you want to scan\nURLs which are disallowed. export default {\n scanner : {\n // disable robots.txt scanning\n robotsTxt : false\n }\n } Sitemap.xml By default, the sitemap config will be read from your /robots.txt . Otherwise, it will fall back to using /sitemap.xml . Note: When a sitemap exists with over 50 paths, it will disable the crawler. Manual sitemap paths You may provide an array of sitemap paths to scan. export default {\n scanner : {\n sitemap : [\n ' /sitemap.xml ' ,\n ' /sitemap2.xml '\n ]\n }\n } Disabling scan If you know your site doesn't have a sitemap, it may make sense to disable it. export default {\n scanner : {\n // disable sitemap scanning\n sitemap : false\n }\n } Crawler When enabled, the crawler will inspect the HTML payload of a page and extract internal links.\nThese internal links will be queued up and scanned if they haven't already been scanned. Disable crawling If you have many pages with many internal links, it may be a good idea to disable the crawling. export default {\n scanner : {\n crawler : false\n }\n } Manually Providing URLs While not recommended for most use cases, you may provide relative URLs within your configuration file, or use the --urls flag. This will disable the crawler and sitemap scanning. Can be provided statically. export default {\n urls : [\n ' /about ' ,\n ' /other-page '\n ] ,\n } Or you can return a function or promise. export default {\n urls : async () => await getUrls ()\n } Specify explicit relative URLs as a comma-separated list. unlighthouse --site https://example.com --urls /about,/other-page .ct-398028{color:#89DDFF;font-style:italic;}\n.light .ct-398028{color:#39ADB5;font-style:italic;}\n.dark .ct-037119{color:#A6ACCD;}\n.ct-037119{color:#EEFFFF;}\n.light .ct-037119{color:#90A4AE;}\n.ct-542793{color:#89DDFF;}\n.light .ct-542793{color:#39ADB5;}\n.ct-821147{color:#F07178;}\n.light .ct-821147{color:#E53935;}\n.dark .ct-649848{color:#676E95;font-style:italic;}\n.ct-649848{color:#546E7A;font-style:italic;}\n.light .ct-649848{color:#90A4AE;font-style:italic;}\n.ct-358248{color:#FF9CAC;}\n.light .ct-358248{color:#FF5370;}\n.ct-083593{color:#C3E88D;}\n.light .ct-083593{color:#91B859;}\n.ct-021512{color:#82AAFF;}\n.light .ct-021512{color:#6182B8;}\n.ct-366012{color:#C792EA;}\n.light .ct-366012{color:#9C3EDA;}\n.ct-902167{color:#FFCB6B;}\n.light .ct-902167{color:#E2931D;}"},{"id":"content:1.guide:recipes:client.md","path":"/guide/recipes/client","dir":"recipes","title":"Modifying UI","description":"","keywords":["Changing columns"],"body":" Modifying UI Changing columns Unlighthouse was built to be hacked. That includes the columns used to display your lighthouse data. You can customise the columns to show any aggregated data that is useful for you. See the glossary guide for the columns to understand the API. Example: Replace FCP Column with Server Response export default {\n hooks : {\n ' resolved-config ' : function ( config ) {\n // replace FCP column with server response time\n config . client . columns . performance [ 2 ] = {\n cols : 1 ,\n label : ' Response Time ' ,\n tooltip : ' Time for the server to respond ' ,\n sortKey : ' numericValue ' ,\n key : ' report.audits.server-response-time ' ,\n }\n }\n }\n } .ct-398028{color:#89DDFF;font-style:italic;}\n.light .ct-398028{color:#39ADB5;font-style:italic;}\n.dark .ct-037119{color:#A6ACCD;}\n.ct-037119{color:#EEFFFF;}\n.light .ct-037119{color:#90A4AE;}\n.ct-542793{color:#89DDFF;}\n.light .ct-542793{color:#39ADB5;}\n.ct-821147{color:#F07178;}\n.light .ct-821147{color:#E53935;}\n.ct-366012{color:#C792EA;}\n.light .ct-366012{color:#9C3EDA;}\n.dark .ct-785412{color:#A6ACCD;font-style:italic;}\n.ct-785412{color:#EEFFFF;font-style:italic;}\n.light .ct-785412{color:#90A4AE;font-style:italic;}\n.dark .ct-649848{color:#676E95;font-style:italic;}\n.ct-649848{color:#546E7A;font-style:italic;}\n.light .ct-649848{color:#90A4AE;font-style:italic;}\n.ct-053683{color:#F78C6C;}\n.light .ct-053683{color:#F76D47;}\n.ct-083593{color:#C3E88D;}\n.light .ct-083593{color:#91B859;}"},{"id":"content:1.guide:recipes:improving-accuracy.md","path":"/guide/recipes/improving-accuracy","dir":"recipes","title":"Improving Accuracy","description":"","keywords":["Run Lighthouse Multiple Times Per URL","Reduce Parallel scans"],"body":" Improving Accuracy Run Lighthouse Multiple Times Per URL Lighthouse recommends using multiple scans to improve the overall accuracy of the results. By default Unlighthouse only\nperforms one sample to improve speed. If you'd like to opt in to multiple samples you can do: export default {\n scanner : {\n // scan each URL 3 times and average the results\n samples : 3\n }\n } Reduce Parallel scans By default, the worker will spin up workers for each core your CPU has. This may not be ideal if you want more accuracy\nperformance scores as the extra workload will affect performance metrics. export default {\n puppeteerClusterOptions : {\n // only run 1 worker at a time\n maxConcurrency : 1\n }\n } .ct-398028{color:#89DDFF;font-style:italic;}\n.light .ct-398028{color:#39ADB5;font-style:italic;}\n.dark .ct-037119{color:#A6ACCD;}\n.ct-037119{color:#EEFFFF;}\n.light .ct-037119{color:#90A4AE;}\n.ct-542793{color:#89DDFF;}\n.light .ct-542793{color:#39ADB5;}\n.ct-821147{color:#F07178;}\n.light .ct-821147{color:#E53935;}\n.dark .ct-649848{color:#676E95;font-style:italic;}\n.ct-649848{color:#546E7A;font-style:italic;}\n.light .ct-649848{color:#90A4AE;font-style:italic;}\n.ct-053683{color:#F78C6C;}\n.light .ct-053683{color:#F76D47;}"},{"id":"content:1.guide:recipes:large-sites.md","path":"/guide/recipes/large-sites","dir":"recipes","title":"Handling large sites","description":"Unlighthouse is configured by default to run on any sized site and only perform useful scans.","keywords":["Default configuration","Manually select URLs","Provide Route Definitions (optional)","Exclude URL Patterns","Include URL Patterns","Change Dynamic Sampling Limit","Disabling Sampling"],"body":" Handling large sites Unlighthouse is configured by default to run on any sized site and only perform useful scans. Default configuration Unlighthouse is configured by default to work on large sites. If you're scanning a smaller site you may consider\nchanging some of the following: ignoreI18nPages enabled maxRoutes set to 200 skipJavascript enabled samples set to 1 throttling disabled crawler enabled dynamicSampling set to 5 For example, when scanning a blog with thousands of posts, it may be redundant to scan every single blog post, as the\nDOM is very similar. Using the configuration we can select exactly how many posts should be scanned. Manually select URLs You can configure Unlighthouse to use an explicit list of relative paths. This can be useful if you have a fairly complex\nand large site. See Manually providing URLs for more information. Provide Route Definitions (optional) To make the most intelligent sampling decisions, Unlighthouse needs to know which page files are available. When running\nusing the\nintegration API, Unlighthouse will automatically provide this information. Using the CLI you should follow the providing route definitions guide. Note: When no route definitions are provided it will match based on URL fragments, i.e /blog/post-slug-3 will be\nmapped to\n blog-slug . Exclude URL Patterns Paths to ignore from scanning. For example, if your site has a documentation section, that doesn't need to be scanned. export default {\n scanner : {\n exclude : [\n ' /docs/* '\n ]\n }\n } Include URL Patterns Explicitly include paths; this will exclude any paths not listed here. For example, if you run a blog and want to only scan your article and author pages. export default {\n scanner : {\n include : [\n ' /articles/* ' ,\n ' /authors/* '\n ]\n }\n } Change Dynamic Sampling Limit By default, a URLs will be matched to a specific route definition 5 times. You can change the sample limit with: export default {\n scanner : {\n // see 20 samples for each page file\n dynamicSampling : 20\n }\n } Disabling Sampling In cases where the route definitions aren't provided, a less-smart sampling will occur where URLs under the same parent\nwill be sampled. For these instances you may want to disable the sample as follows: export default {\n scanner : {\n // no dynamic sampling\n dynamicSampling : false\n }\n } .ct-398028{color:#89DDFF;font-style:italic;}\n.light .ct-398028{color:#39ADB5;font-style:italic;}\n.dark .ct-037119{color:#A6ACCD;}\n.ct-037119{color:#EEFFFF;}\n.light .ct-037119{color:#90A4AE;}\n.ct-542793{color:#89DDFF;}\n.light .ct-542793{color:#39ADB5;}\n.ct-821147{color:#F07178;}\n.light .ct-821147{color:#E53935;}\n.ct-083593{color:#C3E88D;}\n.light .ct-083593{color:#91B859;}\n.dark .ct-649848{color:#676E95;font-style:italic;}\n.ct-649848{color:#546E7A;font-style:italic;}\n.light .ct-649848{color:#90A4AE;font-style:italic;}\n.ct-053683{color:#F78C6C;}\n.light .ct-053683{color:#F76D47;}\n.ct-358248{color:#FF9CAC;}\n.light .ct-358248{color:#FF5370;}"},{"id":"content:1.guide:recipes:spa.md","path":"/guide/recipes/spa","dir":"recipes","title":"Handling SPAs","description":"Unlighthouse assumes that the page being scanned is SSR,\nmeaning that it can parse internal links without executing the javascript.","keywords":["Wait for Javascript"],"body":" Handling SPAs Unlighthouse assumes that the page being scanned is SSR,\nmeaning that it can parse internal links without executing the javascript. By not executing javascript, Unlighthouse makes use of a basic fetch of the page HTML, decreasing scan time. If you're using an SPA and relying on the scanner.crawler mode for URL discovery, you may want to change this behaviour. Wait for Javascript By toggling this option, the HTML payload will be extracted by puppeteer once javascript is executed. export default {\n scanner : {\n skipJavascript : false\n }\n } .ct-398028{color:#89DDFF;font-style:italic;}\n.light .ct-398028{color:#39ADB5;font-style:italic;}\n.dark .ct-037119{color:#A6ACCD;}\n.ct-037119{color:#EEFFFF;}\n.light .ct-037119{color:#90A4AE;}\n.ct-542793{color:#89DDFF;}\n.light .ct-542793{color:#39ADB5;}\n.ct-821147{color:#F07178;}\n.light .ct-821147{color:#E53935;}\n.ct-358248{color:#FF9CAC;}\n.light .ct-358248{color:#FF5370;}"},{"id":"content:2.integrations:0.cli.md","path":"/integrations/cli","dir":"integrations","title":"CLI","description":"Using the Unlighthouse CLI is the primary way to scan entire production sites.","keywords":["Setup","Usage","Configuration"],"body":" CLI Using the Unlighthouse CLI is the primary way to scan entire production sites. Setup npx unlighthouse --site < your-sit e >\n # OR pnpm dlx unlighthouse --site Usage Once installed globally you'll have access to Unlighthouse through the unlighthouse binary. Do a the default scan. unlighthouse --site example.com --debug Run without caching, throttle the requests and do 3 samples. unlighthouse --site example.com --debug --no-cache --throttle --samples 3 Configuration Configuring the CLI can be done either through the CLI arguments or through a config file. See the Configuration section for more details and the guides. CLI Options Options -v, --version Display version number. --site Host URL to scan. --root Define the project root. --config-file Path to config file. --output-path Path to save the contents of the client and reports to. --cache Enable the caching. --no-cache Disable the caching. --desktop Simulate device as desktop. --mobile Simulate device as mobile. --throttle Enable the throttling. --samples Specify the amount of samples to run. --sitemaps Comma separated list of sitemaps to use for scanning. --urls Specify explicit relative paths as a comma-separated list. e.g. unlighthouse --site unlighthouse.dev --urls /guide,/api,/config --exclude-urls Specify relative paths (string or regex) to exclude from scanning as a comma-separated list. e.g. unlighthouse --site unlighthouse.dev --exclude-urls /guide/.*,/api/.* --include-urls Specify relative paths (string or regex) to include as a comma-separated list. e.g. unlighthouse --site unlighthouse.dev --include-urls /guide/.* --enable-javascript When inspecting the HTML wait for the javascript to execute. Useful for SPAs. --disable-javascript When inspecting the HTML, don't wait for the javascript to execute. --enable-i18n-pages Enable scanning pages which use x-default. --disable-i18n-pages Disable scanning pages which use x-default. --disable-dynamic-sampling Disable dynamic sampling of paths. --extra-headers Extra headers to send with the requests. --default-query-params Default query params to send with the requests. -d, --debug Debug. Enable debugging in the logger. -h, --help Display available CLI options Config File If you want to configure Unlighthouse, you can create a unlighthouse.config.ts file in your cwd. export default {\n site : ' example.com ' ,\n debug : true ,\n scanner : {\n device : ' desktop '\n }\n } .ct-902167{color:#FFCB6B;}\n.light .ct-902167{color:#E2931D;}\n.dark .ct-037119{color:#A6ACCD;}\n.ct-037119{color:#EEFFFF;}\n.light .ct-037119{color:#90A4AE;}\n.ct-083593{color:#C3E88D;}\n.light .ct-083593{color:#91B859;}\n.ct-542793{color:#89DDFF;}\n.light .ct-542793{color:#39ADB5;}\n.dark .ct-649848{color:#676E95;font-style:italic;}\n.ct-649848{color:#546E7A;font-style:italic;}\n.light .ct-649848{color:#90A4AE;font-style:italic;}\n.ct-053683{color:#F78C6C;}\n.light .ct-053683{color:#F76D47;}\n.ct-398028{color:#89DDFF;font-style:italic;}\n.light .ct-398028{color:#39ADB5;font-style:italic;}\n.ct-821147{color:#F07178;}\n.light .ct-821147{color:#E53935;}\n.ct-358248{color:#FF9CAC;}\n.light .ct-358248{color:#FF5370;}"},{"id":"content:2.integrations:1.ci.md","path":"/integrations/ci","dir":"integrations","title":"CI","description":"Using the Unlighthouse CI helps you to avoid regressions on your entire sites Google Lighthouse issues.","keywords":["Install","Usage","Configuration","Github Actions & Netlify Example"],"body":" CI Using the Unlighthouse CI helps you to avoid regressions on your entire sites Google Lighthouse issues. Install Unlighthouse aims to keep the installation size small, for this reason it depends natively on your locally installed chrome. To use Unlighthouse in a CI context, you'll need to install puppeteer alongside the cli. npm install -g @unlighthouse/cli puppeteer\n # yarn global add @unlighthouse/cli puppeteer\n # pnpm install -g @unlighthouse/cli puppeteer Usage Reporting You may want to generate reports that can be consumed by other tools. To do you can use the reporter options: json - A simple JSON report which contains the URL and top level scores. This is the default. jsonExpanded - A full JSON report which contains the URL, score, metric and category breakdowns. csv - A simple CSV report which contains the URL and score. csvExpanded - A full CSV report which contains the URL, score, metric and category breakdowns. false - Don't generate a report. You can specify the reporter option with the --reporter flag or the ci.reporter config option. # Run the CI with an expanded JSON report\n unlighthouse-ci --site < your-sit e > --reporter jsonExpanded export default {\n ci : {\n reporter : ' jsonExpanded '\n }\n } Budget assertions Unlighthouse simplifies budget assertions. You can provide a single budget number which will be used\nto validate all pages and on all selected categories. # Run the CI with a budget, will fail if any pages report any category less than 50\n unlighthouse-ci --site < your-sit e > --budget 50 Alternatively, you can provide a configuration file with a list of budgets for each category. export default {\n site : ' https://example.com ' ,\n ci : {\n budget : {\n ' performance ' : 50 ,\n ' accessibility ' : 100 ,\n ' best-practices ' : 90 ,\n ' seo ' : 90 ,\n }\n }\n } # Run in the directory the unlighthouse.config.ts is in\n unlighthouse-ci Build static report Examples https://vue-demo.unlighthouse.dev/ https://inspect.unlighthouse.dev/ Pass the --build-static flag to the binary to generate the static files needed to host the report. # NPM\n unlighthouse-ci --site harlanzw.com --debug --build-static This will generate files in your outputPath ( .unlighthouse by default). You can upload the directory client to a static host from there. Configuration Configuring the CLI can be done either through the CI arguments or through a config file. CI Options Options -v, --version Display version number. --site Host URL to scan. --root Define the project root. --config-file Path to config file. --output-path Path to save the contents of the client and reports to. --budget Budget (1-100), the minimum score which can pass. --reporter Which reporter to use. Options are csv, json, csvExpanded, jsonExpanded. --build-static Build a static website for the reports which can be uploaded. --cache Enable the caching. --no-cache Disable the caching. --throttle Enable the throttling. --samples Specify the amount of samples to run. --urls Specify explicit relative URLs as a comma-separated list. --router-prefix The URL path prefix for the client and API to run from. --enable-javascript When inspecting the HTML wait for the javascript to execute. Useful for SPAs. --disable-javascript When inspecting the HTML, don't wait for the javascript to execute. --enable-i18n-pages Enable scanning pages which use x-default. --disable-i18n-pages Disable scanning pages which use x-default. -d, --debug Debug. Enable debugging in the logger. -h, --help Display available CLI options Config File If you want to configure Unlighthouse, you can create a unlighthouse.config.ts file in your cwd. export default {\n site : ' example.com ' ,\n debug : true ,\n scanner : {\n device : ' desktop '\n }\n } See the Configuration section for more details and the guides. Github Actions & Netlify Example This example is for Github Actions and deploys a static client build to Netlify. name: Assertions and static report\n \n on:\n workflow_dispatch:\n \n jobs:\n demo:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v2\n with:\n fetch-depth: 0\n \n - name: Install Dependencies\n run: npm install -g @unlighthouse/cli puppeteer netlify-cli\n \n - name: Unlighthouse assertions and client\n run: unlighthouse-ci --site --budget 75 --build-static\n \n - name: Deploy\n run: netlify deploy --dir=.unlighthouse --prod --message=\"New Release Deploy from GitHub Actions\"\n env:\n NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}\n NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }} .ct-902167{color:#FFCB6B;}\n.light .ct-902167{color:#E2931D;}\n.dark .ct-037119{color:#A6ACCD;}\n.ct-037119{color:#EEFFFF;}\n.light .ct-037119{color:#90A4AE;}\n.ct-083593{color:#C3E88D;}\n.light .ct-083593{color:#91B859;}\n.dark .ct-649848{color:#676E95;font-style:italic;}\n.ct-649848{color:#546E7A;font-style:italic;}\n.light .ct-649848{color:#90A4AE;font-style:italic;}\n.ct-542793{color:#89DDFF;}\n.light .ct-542793{color:#39ADB5;}\n.ct-398028{color:#89DDFF;font-style:italic;}\n.light .ct-398028{color:#39ADB5;font-style:italic;}\n.ct-821147{color:#F07178;}\n.light .ct-821147{color:#E53935;}\n.ct-053683{color:#F78C6C;}\n.light .ct-053683{color:#F76D47;}\n.ct-358248{color:#FF9CAC;}\n.light .ct-358248{color:#FF5370;}"},{"id":"content:2.integrations:3.nuxt.md","path":"/integrations/nuxt","dir":"integrations","title":"Nuxt","description":"Using the Unlighthouse Nuxt module allows you to close the feedback loop in fixing your Google Lighthouse issues in your development site.","keywords":["Install","Usage","Configuration"],"body":" Nuxt This integration is now deprecated and will be removed in the v1 major release.\nRead more about integration deprecations . Using the Unlighthouse Nuxt module allows you to close the feedback loop in fixing your Google Lighthouse issues in your\ndevelopment site. Install yarn add -D @unlighthouse/nuxt npm install -D @unlighthouse/nuxt pnpm add -D @unlighthouse/nuxt Git ignore reports Unlighthouse will save your reports in outputDir ( .unlighthouse by default),\nit's recommended you .gitignore these files. .unlighthouse Usage To begin using Unlighthouse, you'll need to add the module to buildModules . When you run your Nuxt app, it will give you the URL of client, only once you visit the client will Unlighthouse start. Nuxt 3 import { defineNuxtConfig } from ' nuxt3 '\n \n export default defineNuxtConfig ( {\n modules : [\n ' @unlighthouse/nuxt ' ,\n ] ,\n } ) Nuxt 2 export default {\n buildModules : [\n ' @unlighthouse/nuxt ' ,\n ] ,\n } Type support can be added by adding the @unlighthouse/nuxt module to your plugins . Nuxt v3 will automatically add type support. {\n \" compilerOptions \" : {\n \" types \" : [\n \" @unlighthouse/nuxt \"\n ]\n }\n } Configuration You can either configure Unlighthouse via the unlighthouse key in your Nuxt config, or you can provide a unlighthouse.config.ts file\nin the root directory. Example export default {\n unlighthouse : {\n scanner : {\n // simulate a desktop device\n device : ' desktop ' ,\n }\n }\n } .ct-902167{color:#FFCB6B;}\n.light .ct-902167{color:#E2931D;}\n.dark .ct-037119{color:#A6ACCD;}\n.ct-037119{color:#EEFFFF;}\n.light .ct-037119{color:#90A4AE;}\n.ct-083593{color:#C3E88D;}\n.light .ct-083593{color:#91B859;}\n.ct-398028{color:#89DDFF;font-style:italic;}\n.light .ct-398028{color:#39ADB5;font-style:italic;}\n.ct-542793{color:#89DDFF;}\n.light .ct-542793{color:#39ADB5;}\n.ct-821147{color:#F07178;}\n.light .ct-821147{color:#E53935;}\n.ct-021512{color:#82AAFF;}\n.light .ct-021512{color:#6182B8;}\n.ct-366012{color:#C792EA;}\n.light .ct-366012{color:#9C3EDA;}\n.dark .ct-649848{color:#676E95;font-style:italic;}\n.ct-649848{color:#546E7A;font-style:italic;}\n.light .ct-649848{color:#90A4AE;font-style:italic;}"},{"id":"content:2.integrations:4.vite.md","path":"/integrations/vite","dir":"integrations","title":"Vite","description":"Using the Unlighthouse Vite plugin allows you to close the feedback loop in fixing your Google Lighthouse issues in your development site.","keywords":["Install","Usage","Configuration"],"body":" Vite This integration is now deprecated and will be removed in the v1 major release.\nRead more about integration deprecations . Using the Unlighthouse Vite plugin allows you to close the feedback loop in fixing your Google Lighthouse issues in your\ndevelopment site. Install yarn add -D @unlighthouse/vite npm install -D @unlighthouse/vite pnpm add -D @unlighthouse/vite Git ignore reports Unlighthouse will save your reports in outputDir ( .unlighthouse by default),\nit's recommended you .gitignore these files. .unlighthouse Usage To begin using Unlighthouse, you'll need to add the plugin to plugins . When you run your Vite app, it will give you the URL of client, only once you visit the client will Unlighthouse start. import Unlighthouse from ' @unlighthouse/vite '\n \n export default defineConfig ( {\n plugins : [\n Unlighthouse ( {\n // config\n } )\n ]\n } ) Providing Route Definitions If you're using the vite-plugin-pages plugin, you can provide route definitions to Unlighthouse. You will need to hook into the plugin using the following code. import { useUnlighthouse } from ' unlighthouse '\n \n export default defineConfig ( {\n plugins : [\n Pages ( {\n // ...\n onRoutesGenerated ( routes ) {\n // tell Unlighthouse about the routes\n const unlighthouse = useUnlighthouse ()\n if ( unlighthouse ?. hooks )\n hooks . callHook ( ' route-definitions-provided ' , routes )\n \n }\n } ) ,\n ]\n } ) Configuration You can either configure Unlighthouse via the plugin, or you can provide a config file file\nin the root directory. Example export default defineConfig ( {\n plugins : [\n Unlighthouse ( {\n scanner : {\n // simulate a desktop device\n device : ' desktop ' ,\n }\n } )\n ]\n } ) .ct-902167{color:#FFCB6B;}\n.light .ct-902167{color:#E2931D;}\n.dark .ct-037119{color:#A6ACCD;}\n.ct-037119{color:#EEFFFF;}\n.light .ct-037119{color:#90A4AE;}\n.ct-083593{color:#C3E88D;}\n.light .ct-083593{color:#91B859;}\n.ct-398028{color:#89DDFF;font-style:italic;}\n.light .ct-398028{color:#39ADB5;font-style:italic;}\n.ct-542793{color:#89DDFF;}\n.light .ct-542793{color:#39ADB5;}\n.ct-021512{color:#82AAFF;}\n.light .ct-021512{color:#6182B8;}\n.ct-821147{color:#F07178;}\n.light .ct-821147{color:#E53935;}\n.dark .ct-649848{color:#676E95;font-style:italic;}\n.ct-649848{color:#546E7A;font-style:italic;}\n.light .ct-649848{color:#90A4AE;font-style:italic;}\n.dark .ct-785412{color:#A6ACCD;font-style:italic;}\n.ct-785412{color:#EEFFFF;font-style:italic;}\n.light .ct-785412{color:#90A4AE;font-style:italic;}\n.ct-366012{color:#C792EA;}\n.light .ct-366012{color:#9C3EDA;}"},{"id":"content:2.integrations:webpack.md","path":"/integrations/webpack","dir":"integrations","title":"Webpack","description":"Using the Unlighthouse webpack plugin allows you to close the feedback loop in fixing your Google Lighthouse issues in your development site.","keywords":["Install","Usage","Configuration"],"body":" Webpack This integration is now deprecated and will be removed in the v1 major release.\nRead more about integration deprecations . Using the Unlighthouse webpack plugin allows you to close the feedback loop in fixing your Google Lighthouse issues in\nyour development site. Install yarn add -D @unlighthouse/webpack npm install -D @unlighthouse/webpack pnpm add -D @unlighthouse/webpack Git ignore reports Unlighthouse will save your reports in outputDir ( .unlighthouse by default),\nit's recommended you .gitignore these files. .unlighthouse Usage To begin using Unlighthouse, you'll need to add extend your webpack configuration. When you run your webpack app, it will give you the URL of client, only once you visit the client will Unlighthouse\nstart. webpack.config.js example import Unlighthouse from ' @unlighthouse/webpack '\n \n export default {\n // ...\n plugins : [\n Unlighthouse ( {\n // config\n } ) ,\n ] ,\n } CJS example const Unlighthouse = require ( ' @unlighthouse/webpack ' )\n \n export default {\n // ...\n plugins : [\n Unlighthouse ( {\n // config\n } ) ,\n ] ,\n } Configuration You can either configure Unlighthouse via the plugin, or you can provide a config file \nin the root directory. Example import Unlighthouse from ' @unlighthouse/webpack '\n \n export default {\n // ...\n plugins : [\n Unlighthouse ( {\n scanner : {\n // simulate a desktop device\n device : ' desktop ' ,\n }\n } ) ,\n ] ,\n } .ct-902167{color:#FFCB6B;}\n.light .ct-902167{color:#E2931D;}\n.dark .ct-037119{color:#A6ACCD;}\n.ct-037119{color:#EEFFFF;}\n.light .ct-037119{color:#90A4AE;}\n.ct-083593{color:#C3E88D;}\n.light .ct-083593{color:#91B859;}\n.ct-398028{color:#89DDFF;font-style:italic;}\n.light .ct-398028{color:#39ADB5;font-style:italic;}\n.ct-542793{color:#89DDFF;}\n.light .ct-542793{color:#39ADB5;}\n.dark .ct-649848{color:#676E95;font-style:italic;}\n.ct-649848{color:#546E7A;font-style:italic;}\n.light .ct-649848{color:#90A4AE;font-style:italic;}\n.ct-821147{color:#F07178;}\n.light .ct-821147{color:#E53935;}\n.ct-021512{color:#82AAFF;}\n.light .ct-021512{color:#6182B8;}\n.ct-366012{color:#C792EA;}\n.light .ct-366012{color:#9C3EDA;}"},{"id":"content:3.api:config.md","path":"/api/config","dir":"api","title":"Config","description":"","keywords":["Configuring Unlighthouse","Root Options","CI Options","Client Options","Discovery Options","Scanner Options","Lighthouse Options","Puppeteer Options","Puppeteer Cluster Options"],"body":" Config Configuring Unlighthouse There are multiple ways to configure Unlighthouse. See the configuration documentation for your implementation. Config file - unlighthouse.config.ts CLI arguments Nuxt module options webpack plugin options Vite plugin options Root Options site Type: string The site that will be scanned. root Type: string Default: cwd() The path that we'll be performing the scan from, this should be the path to the app that represents the site.\nUsing this path we can auto-discover the provider cache Type: boolean Default: true Should reports be saved to the local file system and re-used between runs for the scanned site. Note: This makes use of cache-bursting for when the configuration changes, since this may change the report output. configFile Type: string|null Default: null Load the configuration from a custom config file. By default, it attempts to load configuration\nfrom unlighthouse.config.ts . You can set up multiple configuration files for different sites you want to scan.\nFor example: staging-unlighthouse.config.ts production-unlighthouse.config.ts outputPath Type: string Default: ./lighthouse/ Where to emit lighthouse reports and the runtime client. debug Type: boolean Default: false Display the loggers' debug messages. auth Type: false | { username: string, password: string } Default: false Optional basic auth credentials. cookies Type: false | CookieParam[] Default: false Provide cookies to be set for Axios and Puppeteer requests. extraHeaders Type: false | Record Default: false Provide extra headers to be set for Axios and Puppeteer requests. defaultQueryParams Type: false | QueryObject Default: false Query params to add to every request. hooks Type: NestedHooks Default: {} Hooks to run. See the Hooks section for more information. routerPrefix Type: string Default: '' The URL path prefix for the client and API to run from.\nUseful when you want to serve the application from an existing integrations server. For example, you could run Unlighthouse from /__unlighthouse . export default {\n routerPrefix : ' /__unlighthouse '\n } apiPrefix Type: string Default: /api/ The path that the API should be served from. urls Type: string[]|(() => string[])|(() => Promise) Default: [] Provide a list of URLs that should be used explicitly. Will disable sitemap and crawler. See Manually Providing URLs . CI Options Change the behaviour of unlighthouse in CI mode. ci.budget Type: number|Record, number> Default: null Provide a budget for each page as a numeric total score, or an object mapping the category to the score.\nShould be a number between 1-100. For example, if you wanted to make sure all of your pages met a specific accessibility score, you could do: export default {\n ci : {\n budget : {\n accessibility : 90\n }\n },\n } ci.buildStatic Type: boolean Default: false Injects the required data into the client files, so it can be hosted statically. Combine this with uploading to a site, and you can see the results of your unlighthouse scan on a live site. Client Options See Modifying client for more information. client.columns Type: Record Modify the default columns used on the client. client.groupRoutesKey Type: string Default: route.definition.name Which key to use to group the routes. Discovery Options See Route Definitions for more information. discovery.pagesDir Type: string Default: ./pages The location of the page files that will be matched to the routes. Note: This is for fallback behaviour when the integration doesn't provide a way to gather the route definitions. discovery.supportedExtensions Type: string Default: ['vue', 'md'] Which file extensions in the pages dir should be considered. Scanner Options scanner.customSampling Type: Record Default: {} Setup custom mappings for a regex string to a route definition.\nThis is useful when you have a complex site which doesn't use URL path segments\nto separate pages. See custom sampling for more information. scanner.ignoreI18nPages Type: boolean Default: true When the page HTML is extracted and processed, we look for an x-default link to identify if the page is an i18n\ncopy of another page.\nIf it is, then we skip it because it would be a duplicate scan. scanner.maxRoutes Type: number|false Default: 200 The maximum number of routes that should be processed.\nThis helps avoid issues when the site requires a specific\nconfiguration to be able to run properly scanner.include Type: string[]|null Default: null Paths to explicitly include from the search, this will exclude any paths not listed here. See Include URL Patterns for more information. scanner.exclude Type: string[]|null Default: null Paths to ignore from scanning. See Exclude URL Patterns for more information. scanner.skipJavascript Type: boolean Default: true Does javascript need to be executed in order to fetch internal links and SEO data. Disabling this can speed up scans but may break the parsing. See Handling SPAs for more information. scanner.samples Type: number Default: 1 How many samples of each route should be done. This is used to improve false-positive results. See Run Lighthouse Multiple Times \nand Improving Accuracy for more information. scanner.throttle Type: boolean Default: true Should lighthouse run with throttling enabled. This is an alias for manually configuring lighthouse. Note: This will be disabled by default for local scans. See Toggling Throttling for more information. scanner.crawler Type: boolean Default: true Should the crawler be used to detect URLs. This will parse the HTML of scanned pages for internal links and queue\nthem for scanning. See URL Discovery for more information. scanner.dynamicSampling Type: number|false Default: 5 When a route definition is provided, you're able to configure the worker to sample the dynamic routes to avoid\nredundant route reports. See Change Dynamic Sampling Limit for more information. scanner.robotsTxt Type: boolean Default: true Should the robots.txt file be used for configuration. Sitemap paths and disallows paths will be used to configure the scanner. scanner.sitemap Type: boolean | string[] Default: true Either an array of sitemap paths, or a boolean to enable/disable sitemap scanning. By default, when true is provided or an empty array, it will try and load the sitemap from /sitemap.xml . Note: If you have robotsTxt enabled it will load sitemap config from here. scanner.device Type: boolean | string Default: mobile Alias to switch the viewport dimentions used for scanning. Set to desktop for a viewport of 1350×950. Set to false if you want to manually configure it through lighthouseOptions.formFactor . See Switching between mobile and desktop for more information. Lighthouse Options Changes the default behaviour of Google Lighthouse. See Configure Google Lighthouse for more information. Puppeteer Options Change the behaviour of puppeteer. See puppeteer.connect(options) \nfor all available configurations. Puppeteer Cluster Options Change the behaviour of puppeteer-cluster. By default the concurrency will be set on the CPU cores you have available. See Cluster.launch(options) for available\nconfiguration. .ct-398028{color:#89DDFF;font-style:italic;}\n.light .ct-398028{color:#39ADB5;font-style:italic;}\n.dark .ct-037119{color:#A6ACCD;}\n.ct-037119{color:#EEFFFF;}\n.light .ct-037119{color:#90A4AE;}\n.ct-542793{color:#89DDFF;}\n.light .ct-542793{color:#39ADB5;}\n.ct-821147{color:#F07178;}\n.light .ct-821147{color:#E53935;}\n.ct-083593{color:#C3E88D;}\n.light .ct-083593{color:#91B859;}\n.ct-053683{color:#F78C6C;}\n.light .ct-053683{color:#F76D47;}"},{"id":"content:3.api:glossary.md","path":"/api/glossary","dir":"api","title":"Glossary","description":"","keywords":["Core","Worker","Client"],"body":" Glossary Core Route Definition A route definition is the mapping of a page file (such as a vue component or markdown file), and it's URL path (or paths) that it represents. The page component has multiple representations: static route - name matches the path (/about.vue -> /about/), dynamic route - a query is used to generate a set of paths (/posts/:id.vue -> /posts/my-first-post/) catch-all route where any missed paths will be caught (/404.vue -> /some-missing-page) Additional meta-data is provided to give more context of how the mapping behaves, such as which layout to use, which\nasset chunk it belongs to. Different frameworks represent routes differently, This one is based on Nuxt.js export interface RouteDefinition {\n name : string\n path : string\n component ?: string\n componentBaseName ?: string\n chunkName ?: string\n _name ?: string\n layout ?: string\n } Provider A provider is an integration of Unlighthouse to a specific context, such as a framework or an environment. Each provider has their own unique name and defines how they will provide URLs and route definitions to Unlighthouse. export interface Provider {\n /**\n * Used to debug.\n */\n name ?: string\n /**\n * To match a URL path to a route definition we need a router. Different definitions need different routes.\n */\n mockRouter ?: MockRouter | ( ( routeDefinitions : RouteDefinition [] ) => MockRouter )\n /**\n * The collection of route definitions belonging to the provider. These can be inferred but aren't 100% correct,\n * frameworks that can provide these should do so.\n */\n routeDefinitions ?: RouteDefinition [] | ( () => RouteDefinition [] | Promise < RouteDefinition [] > )\n } Route Report A fairly rigid representation of the puppeteer cluster task results ( extractHtmlPayload , runLighthouseTask ),\ncombined with the normalised route. export interface UnlighthouseRouteReport {\n /**\n * The mapping of tasks with their status.\n */\n tasks : Record < UnlighthouseTask , UnlighthouseTaskStatus >\n /**\n * Path to where the artifacts from a URL scan are saved.\n */\n artifactPath : string\n /**\n * URL of where the artifacts are stored, for static client access.\n */\n artifactUrl : string\n /**\n * The route (URL Path) that the report belongs to.\n */\n route : NormalisedRoute\n /**\n * A unique representation of the route, useful for the API layer.\n */\n reportId : string\n /**\n * The lighthouse result, only set once the task is completed.\n */\n report ?: LighthouseReport\n /**\n * The SEO meta-data, only set once the html payload has been extracted and passed.\n */\n seo ?: {\n alternativeLangDefault ?: string\n title ?: string\n description ?: string\n internalLinks ?: number\n externalLinks ?: number\n favicon ?: string\n og ?: {\n description ?: string\n title ?: string\n image ?: string\n }\n }\n } Unlighthouse Context The context is provided by the createUnlighthouse() or useUnlighthouse() functions. It provides the central\nAPI to interacting with the behaviour of Unlighthouse. export interface UnlighthouseContext {\n /**\n * The mock router being used to match paths to route definitions.\n */\n mockRouter ?: MockRouter\n /**\n * Settings that are computed from runtime data.\n */\n runtimeSettings : RuntimeSettings\n /**\n * Access the hook system, either calling a hook or listening to one.\n */\n hooks : Hookable < UnlighthouseHooks >\n /**\n * User config that has been normalised.\n */\n resolvedConfig : ResolvedUserConfig\n /**\n * The collection of route definitions associated to the site.\n */\n routeDefinitions ?: RouteDefinition []\n /**\n * Discovered routes.\n */\n routes ?: NormalisedRoute []\n /**\n * A reference to the API middleware.\n */\n api : any\n /**\n * A reference to the websocket interface, used to broadcast data.\n */\n ws : WS\n /**\n * Access the worker environment, queue tasks, inspect progress, etc.\n */\n worker : UnlighthouseWorker\n /**\n * Provider details\n */\n provider : Provider\n \n /**\n * To use Unlighthouse with a client, it needs a server / app to register the API and client middleware.\n *\n * @ param arg\n */\n setServerContext : ( arg : ServerContextArg ) => Promise < UnlighthouseContext >\n /**\n * Sets the site URL that will be scanned if it's not known at initialisation.\n * @ param url\n */\n setSiteUrl : ( url : string ) => void\n /**\n * Running Unlighthouse via CI does not require a server or the client so we have a special utility for it.\n */\n setCiContext : () => Promise < UnlighthouseContext >\n /**\n * Start the client and the queue worker. A server context must be provided before this function is called.\n */\n start : () => Promise < UnlighthouseContext >\n } Mock Router Unlighthouse provides intelligent sampling which relies on knowing which URLs map to which files in your project.\nTo achieve this, it needs to create its own router with your files to test any URL that comes through. Different integrations will have different requirements from the router.\nFor example, different frameworks will resolve files that contain substitutes\n(for example /posts/[post].vue may work in one framework but not another). export interface MockRouter { match : ( path : string ) => RouteDefinition } Worker Task The worker will queue a route to run with multiple tasks. A task is a queued job and has their own id and status. Unlighthouse has two core tasks: inspectHtmlTask which dumps the HTML of the URL and extracts SEO data from it (title, description, image, internal links, etc) runLighthouseTask runs the actual lighthouse process on the URL See cluster.task(fn) for more details. /**\n * Tasks that Unlighthouse will run, used to track their status.\n */\n export type UnlighthouseTask = ' inspectHtmlTask ' | ' runLighthouseTask '\n \n /**\n * Each task ran by unlighthouse (extractHtmlPayload, runLighthouseTask) has a specific status which we can expose.\n */\n export type UnlighthouseTaskStatus = ' waiting ' | ' in-progress ' | ' completed ' | ' failed ' Client Columns A column will generally be either a direct mapping to a lighthouse audit (such as console errors) or a computed mapping to\nmultiple lighthouse audits (such as image issues). It can also exist as a mapping to the SEO meta-data (such as meta description). export interface UnlighthouseColumn {\n /**\n * The column header name.\n */\n label : string\n /**\n * If the user hovers over the label they'll see a tooltip for extra context.\n */\n tooltip ?: string\n /**\n * A component instance which should be used to render the column cells contents.\n */\n component ?: () => Promise < unknown >\n /**\n * The key within the UnlighthouseRouteReport that maps to the column, used for automatic value inferring.\n */\n key ?: string\n /**\n * Column sizing definition, needed for a responsive UI.\n */\n cols ?: Partial < Record < WindiResponsiveClasses , number >>\n /**\n * Can the column can be sorted?\n *\n * @ default false\n */\n sortable ?: boolean\n /**\n * The key within the UnlighthouseRouteReport that is used to sort the column. This will default to the key if not provided.\n */\n sortKey ?: string\n /**\n * Extra classes that should be added to the column.\n */\n classes ?: string []\n } .ct-398028{color:#89DDFF;font-style:italic;}\n.light .ct-398028{color:#39ADB5;font-style:italic;}\n.dark .ct-037119{color:#A6ACCD;}\n.ct-037119{color:#EEFFFF;}\n.light .ct-037119{color:#90A4AE;}\n.ct-366012{color:#C792EA;}\n.light .ct-366012{color:#9C3EDA;}\n.ct-902167{color:#FFCB6B;}\n.light .ct-902167{color:#E2931D;}\n.ct-542793{color:#89DDFF;}\n.light .ct-542793{color:#39ADB5;}\n.ct-821147{color:#F07178;}\n.light .ct-821147{color:#E53935;}\n.dark .ct-649848{color:#676E95;font-style:italic;}\n.ct-649848{color:#546E7A;font-style:italic;}\n.light .ct-649848{color:#90A4AE;font-style:italic;}\n.dark .ct-785412{color:#A6ACCD;font-style:italic;}\n.ct-785412{color:#EEFFFF;font-style:italic;}\n.light .ct-785412{color:#90A4AE;font-style:italic;}\n.ct-221247{color:#C792EA;font-style:italic;}\n.light .ct-221247{color:#9C3EDA;font-style:italic;}\n.ct-083593{color:#C3E88D;}\n.light .ct-083593{color:#91B859;}"},{"id":"content:3.api:index.md","path":"/api","dir":"","title":"API","description":"","keywords":["@unlighthouse/core","@unlighthouse/server","Unlighthouse Context","Hooks"],"body":" API @unlighthouse/core Functions exposed from the @unlighthouse/core package. createUnlighthouse Type: (userConfig: UserConfig, provider?: Provider) => Promise This is the entry point to using Unlighthouse, it will initialise Unlighthouse with the provided configuration and an optional provider. When no provider is given, a default provider is created which will try and resolve route definitions and URLs. import { createUnlighthouse } from ' @unlighthouse/core '\n \n createUnlighthouse (\n // config\n { configFile : ' mysite.config.ts ' },\n // provider\n {\n name : ' custom ' ,\n // some custom implementation to find the route definitions\n routeDefinitions : () => generateRouteDefinitions () ,\n }\n ) defineConfig Type: (userConfig: UserConfig) => Promise A simple define wrapper to provide typings to config definitions. This is primarily used when creating a\nconfig file unlighthouse.config.ts /// < reference types = \" unlighthouse \" />\n import { defineConfig } from ' unlighthouse '\n \n export default defineConfig ( {\n site : ' harlanzw.com '\n } ) generateClient Type: (options: GenerateClientOptions) => Promise This copies over the client from @unlighthouse/client to be used to render our scans details. It's publicly exposed to provide a tight integrations for custom client builds, such as the CI build. import { generateClient } from ' @unlighthouse/core '\n \n // ...\n logger . info ( ' Generating static client. ' )\n await generateClient ( { static : true } )\n logger . success ( ` Static client generated at \\` ${ unlighthouse . runtimeSettings . generatedClientPath } \\` , ready for hosting. ` ) useUnlighthouse Type: () => UnlighthouseContext Unlighthouse makes use of a composition API to retain the core state. This allows you to access unlighthouse anywhere ,\nwhich is great to avoid transferring state between your logic. import { useUnlighthouse } from ' @unlighthouse/core '\n \n // access the lighthouse context, pick out the worker\n const { worker } = useUnlighthouse ()\n // force whichever route matches home.md to be re-scanned\n worker . invalidateFile ( ' /home.md ' ) useLogger Type: () => void Get the global logger instance. This is useful for tight unlighthouse integrations which want to make use of the\n debug config. import { useLogger } from ' @unlighthouse/core '\n \n // you need to instantiate the logger to get the instance\n const logger = useLogger ()\n // force whichever route matches home.md to be re-scanned\n logger . debug ( ' Something weird has happened ' ) @unlighthouse/server Functions exposed from the @unlighthouse/server package. This package is used for instances where unlighthouse is running without a provider which has an accessible web server. For instance\nrunning Unlighthouse with the cli provider will use this package. createServer Type: () => Promise Creates a h3 app which uses listhen as a web server.\nThis is used to host the API and the client. import { createServer } from ' @unlighthouse/server '\n \n // ...\n const { server , app } = await createServer ()\n // server is an instance of listhen, app is an instance of h3\n await unlighthouse . setServerContext ( { url : server . url , server : server . server , app } )\n await unlighthouse . start () Unlighthouse Context Functions exposed from unlighthouse context provided by useUnlighthouse() or createUnlighthouse() . start Type: () => Promise Start the client and the queue worker. A server context must be provided before this function is called. setCiContext Type: () => Promise Running Unlighthouse via CI does not require a server or the client, so we have a special utility for it. setServerContext Type: (arg: ServerContextArg) => Promise To use Unlighthouse with a client, it needs a server / app to register the API and client middleware. setSiteUrl Type: (url: string) => void Sets the site URL that will be scanned if it's not known at initialisation. Hooks Unlighthouse provides hooks using hookable which allow you tailor the core behaviour. Hooks can be accessed on the hooks property of the context and will always return a Promise|void . export type HookResult = Promise < void > | void import { useUnlighthouse } from ' @unlighthouse/core '\n \n const { hooks } = useUnlighthouse ()\n \n hooks . hook ( ' task-complete ' , ( path , response ) => {\n console . log ( ' task is finished at path ' , path )\n } ) site-changed Type: (site: string) => HookResult It's possible the site is not known at initialisation, this hook is called when it's set or changed. hooks . hook ( ' site-changed ' , ( site ) => {\n // generate payload for site\n } ) worker-finished Type: () => HookResult Called when the worker has finished processing all queued routes. Will be called multiple times if routes are re-queued. Mostly useful for the CI environment. hooks . hook ( ' worker-finished ' , () => {\n console . log ( ' all done :) ' )\n } ) route-definitions-provided Type: (routeDefinitions: any[]) => HookResult When route definitions are provided to Unlighthouse this function will be called useful for delaying internal logic\nuntil the definitions are found. visited-client Type: () => HookResult Called when a user visits the path of the @unlighthouse/client for the first time. Useful for starting the worker on-demand. // only start when the user wants to see the client\n hooks . hookOnce ( ' visited-client ' , () => {\n unlighthouse . start ()\n } ) task-added Type: (path: string, response: UnlighthouseRouteReport) => HookResult Fired when a new task is added to the queue worker. task-started Type: (path: string, response: UnlighthouseRouteReport) => HookResult Fired when a task has started to work. task-complete Type: (path: string, response: UnlighthouseRouteReport, taskName: string) => HookResult Fired when a task has completed it's work. discovered-internal-links Type: (path: string, internalLinks: string[]) => HookResult Fired when a path discovered internal links, used for \"crawl\" mode. puppeteer:before-goto Type: (page: Page) => HookResult After a page has been visited with puppeteer. Useful for running .ct-398028{color:#89DDFF;font-style:italic;}\n.light .ct-398028{color:#39ADB5;font-style:italic;}\n.dark .ct-037119{color:#A6ACCD;}\n.ct-037119{color:#EEFFFF;}\n.light .ct-037119{color:#90A4AE;}\n.ct-542793{color:#89DDFF;}\n.light .ct-542793{color:#39ADB5;}\n.ct-821147{color:#F07178;}\n.light .ct-821147{color:#E53935;}\n.ct-083593{color:#C3E88D;}\n.light .ct-083593{color:#91B859;}\n.ct-021512{color:#82AAFF;}\n.light .ct-021512{color:#6182B8;}\n.dark .ct-649848{color:#676E95;font-style:italic;}\n.ct-649848{color:#546E7A;font-style:italic;}\n.light .ct-649848{color:#90A4AE;font-style:italic;}\n.ct-366012{color:#C792EA;}\n.light .ct-366012{color:#9C3EDA;}\n.ct-965912{color:#F07178;font-style:italic;}\n.light .ct-965912{color:#E53935;font-style:italic;}\n.ct-221247{color:#C792EA;font-style:italic;}\n.light .ct-221247{color:#9C3EDA;font-style:italic;}\n.ct-228358{color:#C3E88D;font-style:italic;}\n.light .ct-228358{color:#91B859;font-style:italic;}\n.ct-358248{color:#FF9CAC;}\n.light .ct-358248{color:#FF5370;}\n.ct-902167{color:#FFCB6B;}\n.light .ct-902167{color:#E2931D;}\n.dark .ct-785412{color:#A6ACCD;font-style:italic;}\n.ct-785412{color:#EEFFFF;font-style:italic;}\n.light .ct-785412{color:#90A4AE;font-style:italic;}"},{"id":"content:index.md","path":"/","dir":"","title":"Unlighthouse - Site-wide Google Lighthouse","description":"","keywords":["Contributors"],"body":" \n \n \n \n \n Open Demo \n Like Lighthouse, but it scans every single page. Scan your entire site with Google Lighthouse in 2 minutes (on average). Open source, fully configurable with minimal setup. What's included Speedy Scans Take advantage of your CPU with threaded workers and use opportunistic throttling and categories for lightning quick scans. Zero-config Link Crawling Fast, configurable URL discovery using robots.txt, sitemap.xml, internal link crawling and project file scanning. No Time Wasted Fewer URLs to scan with automatic sampling of dynamic routes. Hook up your local project files to make it even smarter. Modern UI View your sites' health as a whole with the Unlighthouse client built with Vite. Easily see, search and sort your pages, re-scan individual pages and more. SEO Goodies View all of your pages titles, share images, meta descriptions, see how many internal and external links you have. Accessibility Summary See how your sites accessibility stacks up, find high-leverage issues to fix easily and visually see colour contrast issues. Generate static reports Use the CI to upload your sites reports and access them all at any time. CI Budget Testing View your sites' health as a whole with the Unlighthouse client built with Vite. Easily see, search and sort your pages, re-scan individual pages and more. Powerful configuration Unlighthouse was built to modify, with isolated packages, robust API and a generous hook system. You can even modify the columns in the client! Contributors This package is made possible by my amazing sponsors. \n \n \n "},{"id":"content:integration-deprecations.md","path":"/integration-deprecations","dir":"","title":"Integration Deprecations","description":"Unlighthouse integrations are being deprecated in favour of the CLI.","keywords":["Background","Why Deprecate?","Upgrading"],"body":" Integration Deprecations These integrations are now deprecated: @unlighthouse/nuxt @unlighthouse/vite @unlighthouse/webpack They will be removed in the next major release (v1). Background When Unlighthouse was being developed, the goal was to make it as simple as possible to use with your development site. To allow for this,\nintegrations\nwhere added that set up Unlighthouse automatically for you. This provided the site URL, automatic rescans on page updates and route discovery, which allowed for smarter sampling of dynamic routes. Why Deprecate? Simply, the integrations are too difficult to maintain, error-prone and provide low-value. In nearly all raised issues related to integration, they weren't needed and the CLI could be used instead. Upgrading You should remove any of the following packages from your project. @unlighthouse/nuxt @unlighthouse/vite @unlighthouse/webpack Instead, you should simply use the CLI. npx unlighthouse --site localhost: 3000 The HMR integration be solved by manually rescanning routes using the UI. The route discovery\nwill still work when scanned in the root directory or an app with pages . .ct-902167{color:#FFCB6B;}\n.light .ct-902167{color:#E2931D;}\n.dark .ct-037119{color:#A6ACCD;}\n.ct-037119{color:#EEFFFF;}\n.light .ct-037119{color:#90A4AE;}\n.ct-083593{color:#C3E88D;}\n.light .ct-083593{color:#91B859;}\n.ct-053683{color:#F78C6C;}\n.light .ct-053683{color:#F76D47;}"}]