UtopiaGuidesIntegrating with JavaScript

Integrating with JavaScript

This guide explains how to integrate JavaScript into your Utopia application.

Using Import Maps

Import maps provide a modern way to manage JavaScript module dependencies. Utopia includes built-in support for import maps through the class Utopia::ImportMap class.

Installing JavaScript Libraries

First, install the library using npm:

$ npm install jquery 

Copy the distribution files to public/_components:

$ bundle exec bake utopia:node:update 

This will copy the library's distribution files (typically from node_modules/*/dist/) to your public/_components/ directory, making them available for local serving.

Creating the Import Map

Create a global import map in lib/my_website/import_map.rb:

require "utopia/import_map" module MyWebsite	IMPORT_MAP = Utopia::ImportMap.build(base: "/_components/") do |map|	map.import("jquery", "./jquery/jquery.js")	end end 

Then load this in lib/my_website.rb:

require_relative "my_website/import_map" 

Adding to Your Pages

Add it to your page template (pages/_page.xnode), using relative_to to adjust paths for the current page:

<html>	<head>	#{MyWebsite::IMPORT_MAP.relative_to(request.path + "/")}	</head>	<body>	<!-- Your content -->	</body> </html> 

Using the Library

Once the import map is set up, you can import and use the library in your scripts:

<script type="module">	// <![CDATA[	import $ from 'jquery';	$(document).ready(function() {	console.log("jQuery is ready!");	});	// ]]> </script> 

Advanced Import Map Features

Using CDN URLs

Import maps support direct CDN imports without downloading files:

IMPORT_MAP = Utopia::ImportMap.build do |map|	map.import("react", "https://esm.sh/react@18")	map.import("vue", "https://cdn.jsdelivr.net/npm/vue@3/dist/vue.esm-browser.js") end 

Nested Base URLs

You can organize imports from different sources using nested with(base:) blocks:

IMPORT_MAP = Utopia::ImportMap.build do |map|	# Local components	map.with(base: "/_components/") do |local|	local.import "app", "./app.js"	end	# CDN imports	map.with(base: "https://cdn.jsdelivr.net/npm/") do |cdn|	cdn.import "lit", "lit@2.7.5/index.js"	cdn.import "lit/decorators.js", "lit@2.7.5/decorators.js"	end end 

Subresource Integrity

Add integrity hashes for enhanced security:

IMPORT_MAP = Utopia::ImportMap.build do |map|	map.import("react", "https://esm.sh/react@18", integrity: "sha384-...") end 

Scoped Imports

Use scopes to resolve imports differently based on the referrer URL (the page or module location where the import is being made):

IMPORT_MAP = Utopia::ImportMap.build do |map|	map.import("utils", "/utils.js")	# When importing from any page under /admin/, use a different utils module	map.scope("/admin/", {"utils" => "/admin/utils.js"}) end 

When you're on a page at /admin/dashboard and you import "utils", it will resolve to /admin/utils.js. On other pages, it resolves to /utils.js.

Traditional JavaScript

You can also use JavaScript by embedding it directly into your HTML, or by creating a JavaScript source file and referencing that.

Embedding Code

When embedding JavaScript directly in XRB templates, wrap the code in CDATA comments to prevent XRB's parser from interpreting special characters like <, >, and &:

<html>	<body>	<script type="text/javascript">	// <![CDATA[	console.log("Hello World")	// ]]>	</script>	</body> </html> 

External Script

In script.js:

console.log("Hello World") 

In your HTML view:

<html>	<body>	<script type="text/javascript" src="script.js"></script>	</body> </html>