[{"data":1,"prerenderedAt":679},["ShallowReactive",2],{"docs-\u002Fdocs\u002Fcontribute\u002Fadding-template-settings\u002F":3,"docs-nav":222},{"id":4,"title":5,"body":6,"description":16,"extension":211,"layout":212,"meta":213,"navGroup":212,"navGroupOrder":212,"navOrder":212,"navTitle":5,"navigation":214,"originalPath":215,"path":216,"redirect":212,"seo":217,"stem":218,"updated":219,"version":220,"__hash__":221},"docs\u002Fdocs\u002Fcontribute\u002Fadding-template-settings.md","Adding Template Settings",{"type":7,"value":8,"toc":197},"minimark",[9,13,17,20,23,26,29,60,65,68,76,79,84,87,118,122,125,137,144,147,155,159,163,178,182,189],[10,11,5],"h1",{"id":12},"adding-template-settings",[14,15,16],"p",{},"Within FlowFuse, each Node-RED instance is created from a Template. The Template defines\na set of preconfigured options for the instance. This includes runtime settings -\nvalues that you would normally expect to set in your Node-RED settings.js file.",[14,18,19],{},"The Template also defines which of those options can be customised by individual instances.",[14,21,22],{},"This guide explains how to add a new Node-RED runtime option to the Template object\nso that it can be customised and passed through to the underlying Node-RED settings.js file.",[14,24,25],{},"This is reasonably straightforward for simple boolean\u002Fstring\u002Fnumeric types.\nFor other types (objects\u002Farrays) it gets more complicated and we don't currently\nhave good examples to follow.",[14,27,28],{},"For the 'simple' cases, the steps are:",[30,31,32,44,52],"ol",{},[33,34,35,36],"li",{},"Update the Frontend\n",[30,37,38,41],{},[33,39,40],{},"Pick a name for the setting, add it to the list of known settings and any\nvalidation logic that is needed",[33,42,43],{},"Add it to the appropriate Template section",[33,45,46,47],{},"Update the runtime\n",[30,48,49],{},[33,50,51],{},"Add it to the known list of settings and any additional validation logic",[33,53,54,55],{},"Update the Launcher\n",[30,56,57],{},[33,58,59],{},"Update the template used to generate settings.js with the new property",[61,62,64],"h2",{"id":63},"_1-updating-the-frontend","1. Updating the Frontend",[14,66,67],{},"There are a set of views in the frontend used to present and edit templates. They\nget used in two different ways:",[30,69,70,73],{},[33,71,72],{},"When creating\u002Fediting a template.\nAll options are available and there is a dropdown that lets the user set the\npolicy on the setting (which controls whether an instance is allowed to override\nthe setting)",[33,74,75],{},"When editing instance settings.\nAll options are shown, but only lets the user modify those that the template\npolicy allows to be changed.",[14,77,78],{},"This reuse of the views saves a lot of code duplication, at the cost of some\ncomplication in implementing it.",[80,81,83],"h3",{"id":82},"_11-pick-a-name-for-the-setting","1.1 - Pick a name for the setting",[14,85,86],{},"The name should try to match its corresponding property in the Node-RED settings.js\nfile. Some thought should be made as to organisation of the properties.",[30,88,89,96,111],{},[33,90,91,92],{},"Edit ",[93,94,95],"code",{},"frontend\u002Fsrc\u002Fpages\u002Fadmin\u002FTemplate\u002Futils.js",[33,97,98,99,102,103,106,107,110],{},"Add the new property name to the ",[93,100,101],{},"templateFields"," and ",[93,104,105],{},"defaultTemplateValues"," objects.\nNotice the names are flat strings with ",[93,108,109],{},"_"," used as a hierarchy separator... that\nwill make more sense if you're looking at the file.",[33,112,113,114,117],{},"If the value needs any sort of validation, add it to ",[93,115,116],{},"templateValidators"," in the\nsame file.",[80,119,121],{"id":120},"_12-add-it-to-the-appropriate-template-section","1.2 - Add it to the appropriate Template section",[14,123,124],{},"Currently there are:",[126,127,128,131,134],"ul",{},[33,129,130],{},"Editor",[33,132,133],{},"Palette",[33,135,136],{},"Environment - a special case that is unlikely to get other options added",[14,138,139,140,143],{},"These each lives in their own file under ",[93,141,142],{},"frontend\u002Fsrc\u002Fpages\u002Fadmin\u002FTemplate\u002Fsections\u002F",".",[14,145,146],{},"Pick an existing setting that most closely matches the setting you want to add\n(ie checkbox or text input), and copy its entry to the appropriate place.",[14,148,149,150,154],{},"Make sure you update ",[151,152,153],"em",{},"all"," of the references of the copied property name to your\nnew property name.",[61,156,158],{"id":157},"_2-updating-the-runtime","2. Updating the Runtime",[80,160,162],{"id":161},"_21-adding-it-to-the-known-list","2.1 - Adding it to the known list",[30,164,165,171],{},[33,166,91,167,170],{},[93,168,169],{},"forge\u002Fdb\u002Fcontrollers\u002FProjectTemplate.js"," to add the new property to the\nlist of known settings.",[33,172,173,174,177],{},"In that same file, update the ",[93,175,176],{},"validateSettings"," function with any additional\nvalidation or data cleansing needed.",[61,179,181],{"id":180},"_3-update-nr-launcher","3. Update nr-launcher",[14,183,184,185,188],{},"In the ",[93,186,187],{},"flowforge-nr-launcher"," repo...",[30,190,191],{},[33,192,91,193,196],{},[93,194,195],{},"lib\u002FruntimeSettings.js"," to include the new setting in the generate settings.js\nfile. Note that you must handle the case where the new setting is not present -\neither by applying a sensible default, or omitting the value.",{"title":198,"searchDepth":199,"depth":199,"links":200},"",4,[201,207,210],{"id":63,"depth":202,"text":64,"children":203},2,[204,206],{"id":82,"depth":205,"text":83},3,{"id":120,"depth":205,"text":121},{"id":157,"depth":202,"text":158,"children":208},[209],{"id":161,"depth":205,"text":162},{"id":180,"depth":202,"text":181},"md",null,{},true,"contribute\u002Fadding-template-settings.md","\u002Fdocs\u002Fcontribute\u002Fadding-template-settings",{"title":5,"description":16},"docs\u002Fcontribute\u002Fadding-template-settings","2024-07-19 20:33:52 +0530","2.33.2","5UAbquyuYLqkEpDaJrihf4bBJqHFvgjVo8mH_7P4ARE",[223,231,250,262],{"name":224,"order":225,"children":226},"FlowFuse User Manuals",1,[227],{"title":228,"path":229,"group":224,"groupOrder":225,"order":202,"children":230},"FlowFuse API","\u002Fdocs\u002Fapi",[],{"name":232,"order":199,"children":233},"FlowFuse Self-Hosted",[234,238],{"title":235,"path":236,"group":232,"groupOrder":199,"order":225,"children":237},"Quick Start","\u002Fdocs\u002Fquick-start",[],{"title":239,"path":240,"group":232,"groupOrder":199,"order":205,"children":241},"Upgrading FlowFuse","\u002Fdocs\u002Fupgrade",[242,246],{"title":243,"path":244,"order":212,"children":245},"Installing a license","\u002Fdocs\u002Fupgrade\u002Fopen-source-to-premium",[],{"title":247,"path":248,"order":212,"children":249},"Upgrading the Node-RED version","\u002Fdocs\u002Fupgrade\u002Fnodered-version",[],{"name":251,"order":252,"children":253},"Support",5,[254,258],{"title":255,"path":256,"group":251,"groupOrder":252,"order":205,"children":257},"Premium Support","\u002Fdocs\u002Fpremium-support",[],{"title":259,"path":260,"group":251,"groupOrder":252,"order":212,"children":261},"Debugging Node-RED issues","\u002Fdocs\u002Fdebugging",[],{"name":263,"order":212,"children":264},"Other",[265,313,325,402,451,470,544,555],{"title":266,"path":267,"order":212,"children":268},"admin","\u002Fdocs\u002Fadmin",[269,273,285,293,297,301,305,309],{"title":270,"path":271,"order":225,"children":272},"Administering FlowFuse","\u002Fdocs\u002Fadmin\u002Fintroduction",[],{"title":274,"path":275,"order":212,"children":276},"Configuring Single Sign-On (SSO)","\u002Fdocs\u002Fadmin\u002Fsso",[277,281],{"title":278,"path":279,"order":212,"children":280},"LDAP SSO","\u002Fdocs\u002Fadmin\u002Fsso\u002Fldap",[],{"title":282,"path":283,"order":212,"children":284},"SAML SSO","\u002Fdocs\u002Fadmin\u002Fsso\u002Fsaml",[],{"title":286,"path":287,"order":212,"children":288},"hardening","\u002Fdocs\u002Fadmin\u002Fhardening",[289],{"title":290,"path":291,"order":212,"children":292},"Kubernetes Hardening","\u002Fdocs\u002Fadmin\u002Fhardening\u002Fkubernetes",[],{"title":294,"path":295,"order":212,"children":296},"Monitoring","\u002Fdocs\u002Fadmin\u002Fmonitoring",[],{"title":298,"path":299,"order":212,"children":300},"Observability","\u002Fdocs\u002Fadmin\u002Fobservability",[],{"title":302,"path":303,"order":212,"children":304},"Soft Launch Enablement","\u002Fdocs\u002Fadmin\u002Ffeature-flags",[],{"title":306,"path":307,"order":212,"children":308},"Telemetry","\u002Fdocs\u002Fadmin\u002Ftelemetry",[],{"title":310,"path":311,"order":212,"children":312},"User Management","\u002Fdocs\u002Fadmin\u002Fuser-management",[],{"title":314,"path":315,"order":212,"children":316},"cloud","\u002Fdocs\u002Fcloud",[317,321],{"title":318,"path":319,"order":225,"children":320},"Introduction","\u002Fdocs\u002Fcloud\u002Fintroduction",[],{"title":322,"path":323,"order":212,"children":324},"FlowFuse Cloud Billing","\u002Fdocs\u002Fcloud\u002Fbilling",[],{"title":326,"path":327,"order":212,"children":328},"contribute","\u002Fdocs\u002Fcontribute",[329,332,334,338,342,346,350,358,394,398],{"title":318,"path":330,"order":225,"children":331},"\u002Fdocs\u002Fcontribute\u002Fintroduction",[],{"title":5,"path":216,"order":212,"children":333},[],{"title":335,"path":336,"order":212,"children":337},"API Design","\u002Fdocs\u002Fcontribute\u002Fapi-design",[],{"title":339,"path":340,"order":212,"children":341},"Creating debug stack containers","\u002Fdocs\u002Fcontribute\u002Fcreating-debug-stack-containers",[],{"title":343,"path":344,"order":212,"children":345},"Database migrations","\u002Fdocs\u002Fcontribute\u002Fdb-migrations",[],{"title":347,"path":348,"order":212,"children":349},"FlowFuse Architecture","\u002Fdocs\u002Fcontribute\u002Farchitecture",[],{"title":351,"path":352,"order":212,"children":353},"Local Install","\u002Fdocs\u002Fcontribute\u002Flocal",[354],{"title":355,"path":356,"order":212,"children":357},"Local Stacks","\u002Fdocs\u002Fcontribute\u002Flocal\u002Fstacks",[],{"title":359,"path":360,"order":212,"children":361},"State Flows","\u002Fdocs\u002Fcontribute\u002Fworkflows",[362,366,370,374,378,382,386,390],{"title":363,"path":364,"order":212,"children":365},"Device Editor","\u002Fdocs\u002Fcontribute\u002Fworkflows\u002Fdevice-editor",[],{"title":367,"path":368,"order":212,"children":369},"Instance states","\u002Fdocs\u002Fcontribute\u002Fworkflows\u002Fproject-states",[],{"title":371,"path":372,"order":212,"children":373},"Invite External Users","\u002Fdocs\u002Fcontribute\u002Fworkflows\u002Finvite-external-user",[],{"title":375,"path":376,"order":212,"children":377},"Project Creation","\u002Fdocs\u002Fcontribute\u002Fworkflows\u002Fproject-create",[],{"title":379,"path":380,"order":212,"children":381},"Reset Password Flow","\u002Fdocs\u002Fcontribute\u002Fworkflows\u002Fpassword-reset",[],{"title":383,"path":384,"order":212,"children":385},"Team creation Flow","\u002Fdocs\u002Fcontribute\u002Fworkflows\u002Fteam-create",[],{"title":387,"path":388,"order":212,"children":389},"User Login Flows","\u002Fdocs\u002Fcontribute\u002Fworkflows\u002Flogin",[],{"title":391,"path":392,"order":212,"children":393},"User Sign up Flow","\u002Fdocs\u002Fcontribute\u002Fworkflows\u002Fsignup",[],{"title":395,"path":396,"order":212,"children":397},"Team Broker","\u002Fdocs\u002Fcontribute\u002Fteam-broker",[],{"title":399,"path":400,"order":212,"children":401},"Working with Feature Flags","\u002Fdocs\u002Fcontribute\u002Ffeature-flags",[],{"title":403,"path":404,"order":212,"children":405},"device-agent","\u002Fdocs\u002Fdevice-agent",[406,410,413,417,421,426],{"title":407,"path":408,"order":225,"children":409},"FlowFuse Device Agent Introduction","\u002Fdocs\u002Fdevice-agent\u002Fintroduction",[],{"title":235,"path":411,"order":202,"children":412},"\u002Fdocs\u002Fdevice-agent\u002Fquickstart",[],{"title":414,"path":415,"order":199,"children":416},"Register your Remote Instance","\u002Fdocs\u002Fdevice-agent\u002Fregister",[],{"title":418,"path":419,"order":252,"children":420},"Running the Agent","\u002Fdocs\u002Fdevice-agent\u002Frunning",[],{"title":422,"path":423,"order":424,"children":425},"Deploying your Flows","\u002Fdocs\u002Fdevice-agent\u002Fdeploy",6,[],{"title":427,"path":428,"order":212,"children":429},"install","\u002Fdocs\u002Fdevice-agent\u002Finstall",[430,435,439,443,447],{"title":431,"path":432,"group":433,"order":225,"children":434},"Overview","\u002Fdocs\u002Fdevice-agent\u002Finstall\u002Foverview","DeviceAgentInstallation",[],{"title":436,"path":437,"group":433,"order":202,"children":438},"Device Agent Installer","\u002Fdocs\u002Fdevice-agent\u002Finstall\u002Fdevice-agent-installer",[],{"title":440,"path":441,"group":433,"order":205,"children":442},"Docker Install","\u002Fdocs\u002Fdevice-agent\u002Finstall\u002Fdocker",[],{"title":444,"path":445,"group":433,"order":199,"children":446},"Kubernetes Install","\u002Fdocs\u002Fdevice-agent\u002Finstall\u002Fkubernetes",[],{"title":448,"path":449,"group":433,"order":252,"children":450},"Manual Install with NPM","\u002Fdocs\u002Fdevice-agent\u002Finstall\u002Fmanual",[],{"title":452,"path":453,"order":212,"children":454},"hardware","\u002Fdocs\u002Fhardware",[455,458,462,466],{"title":431,"path":456,"order":225,"children":457},"\u002Fdocs\u002Fhardware\u002Fintroduction",[],{"title":459,"path":460,"order":202,"children":461},"ctrlX - Node-RED","\u002Fdocs\u002Fhardware\u002Fctrlx-node-red",[],{"title":463,"path":464,"order":205,"children":465},"ctrlX - Device Agent","\u002Fdocs\u002Fhardware\u002Fctrlx-device-agent",[],{"title":467,"path":468,"order":205,"children":469},"Raspberry Pi with Raspbian","\u002Fdocs\u002Fhardware\u002Fraspbian",[],{"title":427,"path":471,"order":212,"children":472},"\u002Fdocs\u002Finstall",[473,476,480,484,504,508,512,516],{"title":431,"path":474,"order":225,"children":475},"\u002Fdocs\u002Finstall\u002Fintroduction",[],{"title":477,"path":478,"order":212,"children":479},"Configuring FlowFuse","\u002Fdocs\u002Finstall\u002Fconfiguration",[],{"title":481,"path":482,"order":212,"children":483},"DNS Setup","\u002Fdocs\u002Finstall\u002Fdns-setup",[],{"title":485,"path":486,"order":212,"children":487},"Docker install","\u002Fdocs\u002Finstall\u002Fdocker",[488,492,496,500],{"title":489,"path":490,"order":212,"children":491},"Add Project Stacks on Docker","\u002Fdocs\u002Finstall\u002Fdocker\u002Fstacks",[],{"title":493,"path":494,"order":212,"children":495},"Docker Engine on Windows","\u002Fdocs\u002Finstall\u002Fdocker\u002Fwindows-docker-ce",[],{"title":497,"path":498,"order":212,"children":499},"Docker from AWS Market Place","\u002Fdocs\u002Finstall\u002Fdocker\u002Faws-marketplace",[],{"title":501,"path":502,"order":212,"children":503},"Docker on Digital Ocean","\u002Fdocs\u002Finstall\u002Fdocker\u002Fdigital-ocean",[],{"title":505,"path":506,"order":212,"children":507},"Email configuration","\u002Fdocs\u002Finstall\u002Femail-providers",[],{"title":509,"path":510,"order":212,"children":511},"First Run Setup","\u002Fdocs\u002Finstall\u002Ffirst-run",[],{"title":513,"path":514,"order":212,"children":515},"FlowFuse File Storage","\u002Fdocs\u002Finstall\u002Ffile-storage",[],{"title":517,"path":518,"order":212,"children":519},"Install FlowFuse on Kubernetes","\u002Fdocs\u002Finstall\u002Fkubernetes",[520,524,528,532,536,540],{"title":521,"path":522,"order":212,"children":523},"AWS EKS Installation","\u002Fdocs\u002Finstall\u002Fkubernetes\u002Faws",[],{"title":525,"path":526,"order":212,"children":527},"AWS EKS Installation with Terraform and Helm","\u002Fdocs\u002Finstall\u002Fkubernetes\u002Faws-terraform",[],{"title":529,"path":530,"order":212,"children":531},"Digital Ocean Kubernetes Installation","\u002Fdocs\u002Finstall\u002Fkubernetes\u002Fdigital-ocean",[],{"title":533,"path":534,"order":212,"children":535},"Ingress Controller Migration","\u002Fdocs\u002Finstall\u002Fkubernetes\u002Fingress-controller-migration",[],{"title":537,"path":538,"order":212,"children":539},"Kubernetes Project Stacks","\u002Fdocs\u002Finstall\u002Fkubernetes\u002Fstacks",[],{"title":541,"path":542,"order":212,"children":543},"OpenShift Installation","\u002Fdocs\u002Finstall\u002Fkubernetes\u002Fopenshift",[],{"title":545,"path":546,"order":212,"children":547},"migration","\u002Fdocs\u002Fmigration",[548,551],{"title":318,"path":549,"order":225,"children":550},"\u002Fdocs\u002Fmigration\u002Fintroduction",[],{"title":552,"path":553,"order":212,"children":554},"Node-RED Tools plugin","\u002Fdocs\u002Fmigration\u002Fnode-red-tools",[],{"title":556,"path":557,"order":212,"children":558},"user","\u002Fdocs\u002Fuser",[559,563,567,571,575,580,584,588,592,596,600,604,616,620,624,628,632,636,640,644,648,652,656,660,664,668,671,675],{"title":560,"path":561,"order":225,"children":562},"Getting Started","\u002Fdocs\u002Fuser\u002Fintroduction",[],{"title":564,"path":565,"order":225,"children":566},"Static asset service","\u002Fdocs\u002Fuser\u002Fstatic-asset-service",[],{"title":568,"path":569,"order":202,"children":570},"Bill of Materials","\u002Fdocs\u002Fuser\u002Fbill-of-materials",[],{"title":572,"path":573,"order":202,"children":574},"FlowFuse Concepts","\u002Fdocs\u002Fuser\u002Fconcepts",[],{"title":576,"path":577,"order":578,"children":579},"Instance States","\u002Fdocs\u002Fuser\u002Finstance-states",10,[],{"title":581,"path":582,"order":212,"children":583},"Changing the Stack","\u002Fdocs\u002Fuser\u002Fchangestack",[],{"title":585,"path":586,"order":212,"children":587},"Custom Hostnames","\u002Fdocs\u002Fuser\u002Fcustom-hostnames",[],{"title":589,"path":590,"order":212,"children":591},"Custom Node Packages","\u002Fdocs\u002Fuser\u002Fcustom-npm-packages",[],{"title":593,"path":594,"order":212,"children":595},"Dashboards","\u002Fdocs\u002Fuser\u002Fdashboards",[],{"title":597,"path":598,"order":212,"children":599},"DevOps Pipelines","\u002Fdocs\u002Fuser\u002Fdevops-pipelines",[],{"title":601,"path":602,"order":212,"children":603},"Environment Variables","\u002Fdocs\u002Fuser\u002Fenvvar",[],{"title":605,"path":606,"order":212,"children":607},"FlowFuse Expert","\u002Fdocs\u002Fuser\u002Fexpert",[608,612],{"title":609,"path":610,"order":212,"children":611},"AI in Node-RED","\u002Fdocs\u002Fuser\u002Fexpert\u002Fnode-red-embedded-ai",[],{"title":613,"path":614,"order":212,"children":615},"Chat Interface","\u002Fdocs\u002Fuser\u002Fexpert\u002Fchat",[],{"title":617,"path":618,"order":212,"children":619},"FlowFuse File Nodes","\u002Fdocs\u002Fuser\u002Ffilenodes",[],{"title":621,"path":622,"order":212,"children":623},"FlowFuse MQTT Nodes","\u002Fdocs\u002Fuser\u002Fmqtt-nodes",[],{"title":625,"path":626,"order":212,"children":627},"FlowFuse Persistent Context","\u002Fdocs\u002Fuser\u002Fpersistent-context",[],{"title":629,"path":630,"order":212,"children":631},"FlowFuse Project Nodes","\u002Fdocs\u002Fuser\u002Fprojectnodes",[],{"title":633,"path":634,"order":212,"children":635},"FlowFuse Tables","\u002Fdocs\u002Fuser\u002Fff-tables",[],{"title":637,"path":638,"order":212,"children":639},"Groups","\u002Fdocs\u002Fuser\u002Fdevice-groups",[],{"title":641,"path":642,"order":212,"children":643},"High Availability mode","\u002Fdocs\u002Fuser\u002Fhigh-availability",[],{"title":645,"path":646,"order":212,"children":647},"HTTP Access Tokens","\u002Fdocs\u002Fuser\u002Fhttp-access-tokens",[],{"title":649,"path":650,"order":212,"children":651},"Instance Settings","\u002Fdocs\u002Fuser\u002Finstance-settings",[],{"title":653,"path":654,"order":212,"children":655},"Logging","\u002Fdocs\u002Fuser\u002Flogs",[],{"title":657,"path":658,"order":212,"children":659},"Role-Based Access Control","\u002Fdocs\u002Fuser\u002Frole-based-access-control",[],{"title":661,"path":662,"order":212,"children":663},"Shared Team Library","\u002Fdocs\u002Fuser\u002Fshared-library",[],{"title":665,"path":666,"order":212,"children":667},"Snapshots","\u002Fdocs\u002Fuser\u002Fsnapshots",[],{"title":395,"path":669,"order":212,"children":670},"\u002Fdocs\u002Fuser\u002Fteambroker",[],{"title":672,"path":673,"order":212,"children":674},"Teams","\u002Fdocs\u002Fuser\u002Fteam",[],{"title":676,"path":677,"order":212,"children":678},"User Settings","\u002Fdocs\u002Fuser\u002Fuser-settings",[],1786546037173]