Validate Figma URL and extract file/node IDs using regex

I’m working on a Node.js application that integrates with Figma’s API. I need to validate URLs that users provide to make sure they’re legitimate Figma design or prototype links.

Right now I’m using this basic regex pattern:

/^https\:\/\/www\.figma\.com\/.*/i

The problem is this pattern matches any Figma URL including their homepage and other pages that aren’t actual design files. I only want to match URLs that point to actual design files or prototypes.

Here’s what a valid design file URL looks like:

https://www.figma.com/file/ABC123xyz789/My-Design-Project?node-id=1%3A2

I also need to handle prototype URLs which have proto in the path instead of file.

Since I’m calling the Figma API afterwards, it would be great if I could also capture the file ID and node ID from the URL at the same time. What’s the best way to create a regex that validates these specific URL formats and extracts the needed information?

Been dealing with this exact issue in a client project recently. Instead of trying to craft one massive regex, I found it more reliable to break this down into steps. First validate the basic structure, then extract what you need:

const figmaPattern = /^https:\/\/www\.figma\.com\/(file|proto)\/([A-Za-z0-9]{22})\/.*$/;
const nodePattern = /node-id=([^&]+)/;

const match = url.match(figmaPattern);
if (match) {
    const [, urlType, fileId] = match;
    const nodeMatch = url.match(nodePattern);
    const nodeId = nodeMatch ? decodeURIComponent(nodeMatch[1]) : null;
}

What I learned the hard way is that Figma file IDs are always exactly 22 characters long, so being specific about that length helps catch malformed URLs. Also worth noting that not all valid Figma URLs have node IDs, especially prototype links, so make sure your code handles cases where nodeId might be null.

try this approach thats been working for me:

const match = url.match(/figma\.com\/(file|proto)\/([\w-]+)\/.+node-id=([\d%A-F:]+)/i);
if (match) {
  const [, type, fileId, nodeId] = match;
}

bit simpler than complex regex and catches the main parts you need. just remmeber to url decode the node id before api calls

quick tip from someone who got burned by this - dont forget figma sometimes changes their url structure slightly. i’d suggest also testing your regex against embed urls since they look different but still valid. something like /^https:\/\/www\.figma\.com\/(file|proto|embed)\// might be safer long term. also worth adding a simple length check on extracted ids before hitting their api

Working with Figma URLs in production systems requires handling some nuances that aren’t immediately obvious. The regex approach is solid, but I’d recommend adding validation for the specific character set Figma uses in their file IDs. From my experience, they only use alphanumeric characters without special symbols.

const figmaRegex = /^https:\/\/www\.figma\.com\/(file|proto)\/([A-Za-z0-9]{22})\/(.+?)(?:\?(.*))?$/;

This captures the path after the file ID as well, which can be useful for logging or debugging purposes. One gotcha I encountered was that some URLs include additional query parameters beyond node-id, like viewport settings or comment threads. The optional fourth capture group handles the entire query string, then you can parse it separately to extract just the node-id parameter. This approach proved more robust than trying to match node-id directly in the main pattern, especially when dealing with URLs that users copy from different contexts within Figma.

Here’s a regex pattern that should solve your problem:

const figmaUrlRegex = /^https:\/\/www\.figma\.com\/(file|proto)\/([A-Za-z0-9]+)\/[^?]*(?:\?.*node-id=([^&]+))?/;

This pattern specifically targets the /file/ and /proto/ paths while capturing the file ID as the second group. The node ID becomes the third capture group when present in the query parameters.

I’ve been using something similar in production for about 8 months now and it handles most edge cases well. The key improvement over a basic pattern is that it enforces the specific path structure that actual Figma files use, so random Figma pages won’t match.

One thing to watch out for - the node ID in URLs is URL-encoded, so you’ll get something like 1%3A2 instead of 1:2. You’ll want to decode it with decodeURIComponent() before passing it to the API. Also consider adding some basic validation on the captured file ID length since Figma file IDs follow a consistent format.