(window.webpackJsonp=window.webpackJsonp||[]).push([[9],{78:function(e,t,n){"use strict";n.r(t),n.d(t,"frontMatter",(function(){return o})),n.d(t,"metadata",(function(){return c})),n.d(t,"toc",(function(){return l})),n.d(t,"default",(function(){return b}));var a=n(3),r=n(7),i=(n(0),n(97)),o={id:"contributing",title:"Contributing"},c={unversionedId:"contributing",id:"contributing",isDocsHomePage:!1,title:"Contributing",description:"Getting the source",source:"@site/docs/contributing.md",slug:"/contributing",permalink:"/frigate/contributing",editUrl:"https://github.com/blakeblackshear/frigate/edit/master/docs/docs/contributing.md",version:"current",sidebar:"docs",previous:{title:"MQTT",permalink:"/frigate/usage/mqtt"}},l=[{value:"Getting the source",id:"getting-the-source",children:[{value:"Core, Web, Docker, and Documentation",id:"core-web-docker-and-documentation",children:[]},{value:"Frigate Home Assistant Addon",id:"frigate-home-assistant-addon",children:[]},{value:"Frigate Home Assistant Integration",id:"frigate-home-assistant-integration",children:[]}]},{value:"Core",id:"core",children:[{value:"Prerequisites",id:"prerequisites",children:[]}]},{value:"Web Interface",id:"web-interface",children:[{value:"Prerequisites",id:"prerequisites-1",children:[]},{value:"Making changes",id:"making-changes",children:[]}]},{value:"Documentation",id:"documentation",children:[{value:"Prerequisites",id:"prerequisites-2",children:[]},{value:"Making changes",id:"making-changes-1",children:[]}]}],s={toc:l};function b(e){var t=e.components,n=Object(r.a)(e,["components"]);return Object(i.b)("wrapper",Object(a.a)({},s,n,{components:t,mdxType:"MDXLayout"}),Object(i.b)("h2",{id:"getting-the-source"},"Getting the source"),Object(i.b)("h3",{id:"core-web-docker-and-documentation"},"Core, Web, Docker, and Documentation"),Object(i.b)("p",null,"This repository holds the main Frigate application and all of its dependencies."),Object(i.b)("p",null,"Fork ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"https://github.com/blakeblackshear/frigate.git"}),"blakeblackshear/frigate")," to your own GitHub profile, then clone the forked repo to your local machine."),Object(i.b)("p",null,"From here, follow the guides for:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},Object(i.b)("a",Object(a.a)({parentName:"li"},{href:"#core"}),"Core")),Object(i.b)("li",{parentName:"ul"},Object(i.b)("a",Object(a.a)({parentName:"li"},{href:"#web-interface"}),"Web Interface")),Object(i.b)("li",{parentName:"ul"},Object(i.b)("a",Object(a.a)({parentName:"li"},{href:"#documentation"}),"Documentation"))),Object(i.b)("h3",{id:"frigate-home-assistant-addon"},"Frigate Home Assistant Addon"),Object(i.b)("p",null,"This repository holds the Home Assistant Addon, for use with Home Assistant OS and compatible installations. It is the piece that allows you to run Frigate from your Home Assistant Supervisor tab."),Object(i.b)("p",null,"Fork ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"https://github.com/blakeblackshear/frigate-hass-addons"}),"blakeblackshear/frigate-hass-addons")," to your own Github profile, then clone the forked repo to your local machine."),Object(i.b)("h3",{id:"frigate-home-assistant-integration"},"Frigate Home Assistant Integration"),Object(i.b)("p",null,"This repository holds the custom integration that allows your Home Assistant installation to automatically create entities for your Frigate instance, whether you run that with the ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"#frigate-home-assistant-addon"}),"addon")," or in a separate Docker instance."),Object(i.b)("p",null,"Fork ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"https://github.com/blakeblackshear/frigate-hass-integration"}),"blakeblackshear/frigate-hass-integration")," to your own GitHub profile, then clone the forked repo to your local machine."),Object(i.b)("h2",{id:"core"},"Core"),Object(i.b)("h3",{id:"prerequisites"},"Prerequisites"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},Object(i.b)("a",Object(a.a)({parentName:"li"},{href:"#frigate-core-web-and-docs"}),"Frigate source code")),Object(i.b)("li",{parentName:"ul"},"GNU make"),Object(i.b)("li",{parentName:"ul"},"Docker")),Object(i.b)("h2",{id:"web-interface"},"Web Interface"),Object(i.b)("h3",{id:"prerequisites-1"},"Prerequisites"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},Object(i.b)("a",Object(a.a)({parentName:"li"},{href:"#frigate-core-web-and-docs"}),"Frigate source code")),Object(i.b)("li",{parentName:"ul"},"All ",Object(i.b)("a",Object(a.a)({parentName:"li"},{href:"#core"}),"core")," prerequisites ",Object(i.b)("em",{parentName:"li"},"or")," another running Frigate instance locally available"),Object(i.b)("li",{parentName:"ul"},"Node.js 14")),Object(i.b)("h3",{id:"making-changes"},"Making changes"),Object(i.b)("h4",{id:"1-set-up-a-frigate-instance"},"1. Set up a Frigate instance"),Object(i.b)("p",null,"The Web UI requires an instance of Frigate to interact with for all of its data. You can either run an instance locally (recommended) or attach to a separate instance accessible on your network."),Object(i.b)("p",null,"To run the local instance, follow the ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"#core"}),"core")," development instructions."),Object(i.b)("p",null,"If you won't be making any changes to the Frigate HTTP API, you can attach the web development server to any Frigate instance on your network. Skip this step and go to ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"#3a-run-the-development-server-against-a-non-local-instance"}),"3a"),"."),Object(i.b)("h4",{id:"2-install-dependencies"},"2. Install dependencies"),Object(i.b)("pre",null,Object(i.b)("code",Object(a.a)({parentName:"pre"},{className:"language-console"}),"cd web && npm install\n")),Object(i.b)("h4",{id:"3-run-the-development-server"},"3. Run the development server"),Object(i.b)("pre",null,Object(i.b)("code",Object(a.a)({parentName:"pre"},{className:"language-console"}),"cd web && npm run start\n")),Object(i.b)("h4",{id:"3a-run-the-development-server-against-a-non-local-instance"},"3a. Run the development server against a non-local instance"),Object(i.b)("p",null,"To run the development server against a non-local instance, you will need to provide an environment variable, ",Object(i.b)("inlineCode",{parentName:"p"},"SNOWPACK_PUBLIC_API_HOST")," that tells the web application how to connect to the Frigate API:"),Object(i.b)("pre",null,Object(i.b)("code",Object(a.a)({parentName:"pre"},{className:"language-console"}),"cd web && SNOWPACK_PUBLIC_API_HOST=http://:5000 npm run start\n")),Object(i.b)("h4",{id:"4-making-changes"},"4. Making changes"),Object(i.b)("p",null,"The Web UI is built using ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"https://www.snowpack.dev/"}),"Snowpack"),", ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"https://preactjs.com"}),"Preact"),", and ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"https://tailwindcss.com"}),"Tailwind CSS"),"."),Object(i.b)("p",null,"Light guidelines and advice:"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"Avoid adding more dependencies. The web UI intends to be lightweight and fast to load."),Object(i.b)("li",{parentName:"ul"},"Do not make large sweeping changes. ",Object(i.b)("a",Object(a.a)({parentName:"li"},{href:"https://github.com/blakeblackshear/frigate/discussions/new"}),"Open a discussion on GitHub")," for any large or architectural ideas."),Object(i.b)("li",{parentName:"ul"},"Ensure ",Object(i.b)("inlineCode",{parentName:"li"},"lint")," passes. This command will ensure basic conformance to styles, applying as many automatic fixes as possible, including Prettier formatting.")),Object(i.b)("pre",null,Object(i.b)("code",Object(a.a)({parentName:"pre"},{className:"language-console"}),"npm run lint\n")),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"Add to unit tests and ensure they pass. As much as possible, you should strive to ",Object(i.b)("em",{parentName:"li"},"increase")," test coverage whenever making changes. This will help ensure features do not accidentally become broken in the future.")),Object(i.b)("pre",null,Object(i.b)("code",Object(a.a)({parentName:"pre"},{className:"language-console"}),"npm run test\n")),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},"Test in different browsers. Firefox, Chrome, and Safari all have different quirks that make them unique targets to interact with.")),Object(i.b)("h2",{id:"documentation"},"Documentation"),Object(i.b)("h3",{id:"prerequisites-2"},"Prerequisites"),Object(i.b)("ul",null,Object(i.b)("li",{parentName:"ul"},Object(i.b)("a",Object(a.a)({parentName:"li"},{href:"#frigate-core-web-and-docs"}),"Frigate source code")),Object(i.b)("li",{parentName:"ul"},"Node.js 14")),Object(i.b)("h3",{id:"making-changes-1"},"Making changes"),Object(i.b)("h4",{id:"1-installation"},"1. Installation"),Object(i.b)("pre",null,Object(i.b)("code",Object(a.a)({parentName:"pre"},{className:"language-console"}),"npm run install\n")),Object(i.b)("h4",{id:"2-local-development"},"2. Local Development"),Object(i.b)("pre",null,Object(i.b)("code",Object(a.a)({parentName:"pre"},{className:"language-console"}),"npm run start\n")),Object(i.b)("p",null,"This command starts a local development server and open up a browser window. Most changes are reflected live without having to restart the server."),Object(i.b)("p",null,"The docs are built using ",Object(i.b)("a",Object(a.a)({parentName:"p"},{href:"https://v2.docusaurus.io"}),"Docusaurus v2"),". Please refer to the Docusaurus docs for more information on how to modify Frigate's documentation."),Object(i.b)("h4",{id:"3-build-optional"},"3. Build (optional)"),Object(i.b)("pre",null,Object(i.b)("code",Object(a.a)({parentName:"pre"},{className:"language-console"}),"npm run build\n")),Object(i.b)("p",null,"This command generates static content into the ",Object(i.b)("inlineCode",{parentName:"p"},"build")," directory and can be served using any static contents hosting service."))}b.isMDXComponent=!0},97:function(e,t,n){"use strict";n.d(t,"a",(function(){return u})),n.d(t,"b",(function(){return h}));var a=n(0),r=n.n(a);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function c(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=r.a.createContext({}),b=function(e){var t=r.a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},u=function(e){var t=b(e.components);return r.a.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.a.createElement(r.a.Fragment,{},t)}},d=r.a.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,o=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),u=b(n),d=a,h=u["".concat(o,".").concat(d)]||u[d]||p[d]||i;return n?r.a.createElement(h,c(c({ref:t},s),{},{components:n})):r.a.createElement(h,c({ref:t},s))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=d;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c.mdxType="string"==typeof e?e:a,o[1]=c;for(var s=2;s