arya-blue
luna-amber
luna-blue
luna-green
luna-pink
nova-dark
nova-light
saga-blue
vela-blue
MonacoEditor
The Monaco editor widget was built with extensibility in mind. The PrimeFaces widget is a JSF wrapper component that lets you integrate the editor easily in a JSF page and provides several options for the most common features. Sometimes, however, it may become necessary to customize the editor event further. In that case, you can make use of the extensive client-side JavaScript API provided by the Monaco editor.

To do so, specify the extender option on the editor. This lets you set a custom JavaScript object with several callback methods for the lifecycle of the Monaco editor. For example, you can modify the editor options before the editor is created, or add TypeScript declaration files for improved IntelliSense. The example below loads the declaration files for JQuery from the DefinitelyTyped GitHub repo and adds them to the editor. This enables autocomplete and docs for JQuery function.

For the inline widget, you can just specify a JavaScript expression that evaluates to an extender object. For the framed widget, you will need to specify an URL to a JavaScript file that creates the extender and writes it to window.MonacoEnvironment.Extender. See the panel to the right for more info about the extender object. Please note that for the framed widget, the extender is run in the iframe context and will not have access to JQuery nor to PrimeFaces related functions.

The extenders you see in the example below use the fetch API and other modern JavaScript features. If you need to support old browsers, consider using XMLHttpRequest instead of fetch instead.

Finally, you can also check out the Monaco editor playground which contains many more examples of how you can use the client-side API to customize the editor.
Additional type declarations (JQuery)This example illustrates how you can add custom type declaration files to the editor. It loads the type declarations files for JQuery -- try hovering over the JQuery functions in the editor to the right or try typing some code to see the autocomplete feature in action.

To do so, you should add the beforeCreate to your extender object. Use the third parameter wasLibLoaded to check whether the Monaco editor library was reloaded -- if not, there's no need to add declarations files again.

Then you can add the required type declaration files via monaco.languages.typescript.javascriptDefaults.addExtraLib (if you are editing a JavaScript file) or monaco.languages.typescript.typescriptDefaults.addExtraLib (if you are editing a TypeScript file). See the Monaco editor API DOC for more info on that function.

Finally, you may wonder from where you should load the declaration files. You could add the declaration inline into the extender script, which may be a viable option for small declaration files. For larger files, it is recommended you load the declaration file from a network resource. Note that the beforeCreate hook of the extender may return a Promise. If it does, the Monaco editor widget will wait until that Promise resolves and only create the editor once it does.

See also https://github.com/DefinitelyTyped/DefinitelyTyped, the repository for high quality TypeScript type definitions for many popular JavaScript libraries.
Run
Link to this extender example
Source

                <p:staticMessage id="extenderInfo" severity="info" styleClass="monacoEditorMessage" escape="false"
  summary="#{monacoEditorController.extenderName}" detail="#{monacoEditorController.extenderInfo}" />

<h:panelGrid columns="4">
  <!-- Apply the selected extender -->
  <p:commandLink id="applyExtender" partialSubmit="true" styleClass="ui-button ui-button-text-icon-right"
    actionListener="#{monacoEditorController.onMonacoExtenderRun}"
    process="@this,extenderTabs:monacoExtender,extenderTabs:monacoCss,monacoEditorWrapper" update="customExtenderInline,monacoEditorWrapper">
    <span class="ui-button-icon-right ui-icon ui-c pi pi-play" style="color:white"></span>
    <span class="ui-button-text ui-c" style="color:white">Run</span>
  </p:commandLink>

  <!-- Select extender example -->
  <p:outputLabel for="extenderExample" value="Extender example: " />
  <p:selectOneMenu id="extenderExample" value="#{monacoEditorController.extenderExample}">
    <f:selectItems value="#{monacoEditorController.extenderExamples}" />
    <p:ajax 
      process="extenderInfo,extenderTabs:monacoExtender,extenderTabs:monacoCss,monacoEditorWrapper"
      listener="#{monacoEditorController.onExtenderExampleChange}"
      update="customExtenderInline,extenderInfo,extenderLink,extenderTabs:monacoExtender,extenderTabs:monacoCss,monacoEditorWrapper" />
  </p:selectOneMenu>
  
  <p:link id="extenderLink" href="?example=#{monacoEditorController.extenderExample}" 
    target="_blank"
    value="Link to this extender example"/>
</h:panelGrid>

<div style="display:flex">
  <!-- Monaco editor for editing the extender -->
  <p:tabView id="extenderTabs" style="flex:1">
      <p:tab id="extenderCode" title="Extender">
          <h:panelGroup id="monacoExtenderWrapper" layout="block" styleClass="monacoExtenderBox">
              <pe:monacoEditorFramed id="monacoExtender" widgetVar="monacoExtender"
                  value="#{monacoEditorController.valueExtender}" scheme="file"
                  extender="#{resource['js/monacoExtender.js']}"
                  iframeUrlParams="{extender: 'monaco', language: 'javascript', tsCheck: true, moreDeclarationUrls: ['#{of:escapeJS(resource['primefaces-extensions:monacoeditor/primefaces-monaco-global.d.ts'])}', '#{of:escapeJS(resource['primefaces-extensions:monacoeditor/primefaces-monaco-module.d.ts'])}'], moreDeclarationNames: ['file:///src/primefaces-monaco-global.d.ts', 'file:///src/primefaces-monaco-module.d.ts']}"
                  editorOptions="#{monacoEditorController.editorOptionsExtender}"
                  width="100%" height="500px" autoResize="true"
              />
          </h:panelGroup>
      </p:tab>
      <p:tab id="customCss" title="Custom CSS">
          <h:panelGroup id="monacoCssWrapper" layout="block" styleClass="monacoExtenderBox">
              <pe:monacoEditorFramed id="monacoCss" widgetVar="monacoCss"
                  value="#{monacoEditorController.valueCss}" scheme="file"
                  extender="#{resource['js/monacoExtender.js']}"
                  iframeUrlParams="{extender: 'default'}"
                  language="css"
                  editorOptions="#{monacoEditorController.editorOptionsCss}"
                  width="100%" height="500px" autoResize="true"/>
          </h:panelGroup>
      </p:tab>
  </p:tabView>

  <!-- Actual editor with the extender applied -->
  <!-- window.createShowcaseExtender wraps the createExtender function -->
  <!-- defined in the editor above to catch and display errors. -->
  <h:panelGroup id="monacoEditorWrapper" layout="block" style="flex:1" styleClass="monacoEditorBox">
      <pe:monacoEditor id="monacoEditor" widgetVar="monacoEditor"
          rendered="#{empty monacoEditorController.extenderError}"
          value="#{monacoEditorController.value}"
          extender="window.createShowcaseExtender()"
          editorOptions="#{monacoEditorController.editorOptions}"
          width="100%" height="500px" autoResize="true" />
      <h:panelGroup layout="block" 
        rendered="#{not empty monacoEditorController.extenderError}" styleClass="monacoEditorError">
        <strong>Could not load custom Monaco editor extender, error was:</strong>
        <pre>#{monacoEditorController.extenderError}</pre>
      </h:panelGroup>
  </h:panelGroup>
</div>
            
Components and more
Documentation pe:monacoEditor
Attributes (move mouse over the names to see data types)
Name Description
bindingAn EL expression referring to a server side UIComponent instance in a backing bean.Default is generated.
extenderExtender script: JavaScript expression that evaluates to an extender instance.
idUnique identifier of the component in a namingContainer.Default is generated.
overflowWidgetsDomNodeSearch expression for a component; places overflow widgets inside an external DOM node.
renderedUnique identifier of the component in a namingContainer.Default is generated.
PrimeFaces Extensions Showcase - © 2011-2025,PrimeFaces: 16.0.0-SNAPSHOT,PrimeFaces Extensions: 16.0.0-SNAPSHOT,JSF: Apache MyFaces Core 4.0 - Impl 4.0.3,Server: Apache Tomcat (TomEE)/10.1.52 (10.1.4),Build time: 2026-03-14 23:18