Skip to main content

Making Network Requests

Making network requests with widgets is very similar to making network requests with plugins.

It's mostly the same as in normal JavaScript running directly inside of a web browser: the only caveat is that the APIs for making network requests are provided by the browser, not by the Figma sandbox itself. As a result, you will need to create an <iframe> to access these browser APIs.

The widget below demonstrates this. It creates an invisible <iframe> as a worker, then uses that to make a network request. When it gets the result of that network request, it sets and updates the state of the widget.

code.tsx
const { widget } = figma
const { Text, useSyncedState, useEffect, waitForTask } = widget

function NetworkWidget() {
const [text, setText] = useSyncedState("text", "initial")

useEffect(() => {
waitForTask(new Promise(resolve => {
figma.showUI(__html__, { visible: false })
figma.ui.postMessage({ type: 'networkRequest' })

figma.ui.onmessage = async (msg) => {
// Update the widget state!
setText(msg)

// Resolve the task since we are done!
resolve()
}
}))
})
}

widget.register(NetworkWidget)

The worker (the invisible "UI" which is the content of the <iframe>) is implemented in a separate file referred to by the ui section of manifest.json. Here, the worker simply makes a standard XMLHttpRequest and sends the results back to the main thread.

ui.html
<script>
window.onmessage = async (event) => {
if (event.data.pluginMessage.type === 'networkRequest') {
var request = new XMLHttpRequest()
// This link has random lorem ipsum text
request.open('GET', 'https://cors-anywhere.herokuapp.com/http://www.randomtext.me/download/text/lorem/ul-8/5-15')
request.responseType = 'text'
request.onload = () => {
window.parent.postMessage({pluginMessage: request.response}, '*')
};
request.send()
}
}
</script>

Because widgets run inside a browser environment, Cross-Origin Resource Sharing policies apply. Widget iframes have a null origin, which means that they will only be able to call APIs with Access-Control-Allow-Origin: * (i.e., those that allow access from any origin). In the example above, we use a CORS proxy for simplicity, but it's not something you generally need to or should use.