Angular integration with Monaco Editor

This is a simple example of how to integrate the Monaco Editor into an Angular 21 application.

I tested various approaches, including using ngx-monaco-editor-v2 , but finally settled on a simple manual integration without any additional libraries.

The steps to set up the project are as follows:

# install angular cli
npm install -g @angular/cli
# create a new angular project
ng new angular-monaco-editor
cd angular-monaco-editor

Install monaco editor:

npm install monaco-editor

In angular.json, add the following lines to the "build" -> "options" -> "assets" array to copy the monaco editor assets to the output folder:

{
    "glob": "**/*",
    "input": "node_modules/monaco-editor",
    "output": "/assets/monaco/"
},

In angular.json, make sure "build" -> "options" look something like:

"styles": [
    src/styles.css",
    "node_modules/monaco-editor/min/vs/editor/editor.main.css"
],
"loader": {
    ".ttf": "file"
}

In src/main.ts add (add whatever language you want to support):

export const GLOBAL_MONACO_OPTIONS = { theme: 'vs-light', language: 'javascript' }

;(window as any).MonacoEnvironment = {
    getWorkerUrl: (moduleId: string, label: string) => {
        if (label === 'json') {
            return './assets/monaco/esm/vs/language/json/json.worker.js'
        }
        if (label === 'css' || label === 'scss' || label === 'less') {
            return './assets/monaco/esm/vs/language/css/css.worker.js'
        }
        if (label === 'html' || label === 'handlebars' || label === 'razor') {
            return './assets/monaco/esm/vs/language/html/html.worker.js'
        }
        if (label === 'typescript' || label === 'javascript') {
            return './assets/monaco/esm/vs/language/typescript/ts.worker.js'
        }
        return './assets/monaco/esm/vs/editor/editor.worker.js'
    },
}

In src/app/app.ts, add the following code to initialize the monaco editor:

...
import * as monaco from 'monaco-editor'
...
    private readonly editorDiv = viewChild<ElementRef<HTMLDivElement>>('editor')
    private monacoEditor!: monaco.editor.IStandaloneCodeEditor
...
    ngAfterViewInit() {
        this.monacoEditor = monaco.editor.create(this.editor()!.nativeElement, {
            ...GLOBAL_MONACO_OPTIONS,
            value: `console.log('test')`,
        })
    }
...
    onSave() {
        const code = this.monacoEditor.getValue()
        console.log(code)
    }
...
    

In src/app/app.html

<div #editor style="width: 800px; height: 200px;"></div>

Restart the Angular development server to see the Monaco Editor in action.

 

Imports

Tweak the imports to only import languages we want to support

Instead of

import * as monaco from 'monaco-editor'

Use these imports (here for javascript, python and json)

import * as monaco from 'monaco-editor/esm/vs/editor/editor.api.js'
import 'monaco-editor/esm/vs/basic-languages/javascript/javascript.contribution.js'
import 'monaco-editor/esm/vs/basic-languages/python/python.contribution.js'
import 'monaco-editor/esm/vs/language/json/monaco.contribution.js'
Questions? Read this article on medium.com More about me