JG Docs
Vehicle Studio

API

Get vehicle image URLs from other scripts

JG Vehicle Studio has two exports for getting vehicle image URLs from other scripts. Both work on the client and the server.

getImage

Returns the stored image URL for a vehicle and an ordered list of computed fallback image URLs.

-- works on both client & server
-- imageId is optional and defaults to "default" (the image set ID)
local image, fallbacks = exports["jg-vehiclestudio"]:getImage(spawnCode, imageId)

-- example
local image, fallbacks = exports["jg-vehiclestudio"]:getImage("adder")

-- example: use a specific image set
local orangeImage = exports["jg-vehiclestudio"]:getImage("adder", "orange_bg")
ReturnsTypeDescription
imagestring?Stored image URL for the vehicle & image set, or nil when none is saved
fallbacksstring[]Ordered fallback URLs with {MODEL}, {model}, {HASH} & {hash} tokens resolved

Fallback URLs are candidates only - the export does not check that they exist. Try them in order and use the first one that loads. When a fallback URL has no variable tokens it is treated as a final static fallback, and any configured fallbacks after it are not returned.

getImages

Returns stored image URLs and computed fallback URLs for multiple vehicles in one call.

-- works on both client & server
-- imageId is optional and defaults to "default"
local images = exports["jg-vehiclestudio"]:getImages(spawnCodes, imageId)

-- example
local images = exports["jg-vehiclestudio"]:getImages({ "adder", "zentorno", "t20" })

--[[ example result:
{
  adder = {
    image = "https://images.example.com/jg-vehiclestudio/image/adder.webp?v=1710000000",
    fallbacks = {
      "https://docs.fivem.net/vehicles/adder.webp",
      "https://cfx-nui-jg-vehiclestudio/web/dist/no-vehicle-image.png",
    },
  },
  zentorno = {
    image = nil,
    fallbacks = {
      "https://docs.fivem.net/vehicles/zentorno.webp",
      "https://cfx-nui-jg-vehiclestudio/web/dist/no-vehicle-image.png",
    },
  },
}
]]
ReturnsTypeDescription
imagestable<spawnCode, entry>One entry per requested vehicle
entry.imagestring?Stored image URL for that vehicle, or nil
entry.fallbacksstring[]Ordered computed fallback image URLs

Image IDs

imageId is the image set ID. If you don't pass one, Vehicle Studio uses "default". Use the same image ID you selected when photographing the vehicle in Vehicle Studio.

local defaultImage = exports["jg-vehiclestudio"]:getImage("adder")
local orangeImage = exports["jg-vehiclestudio"]:getImage("adder", "orange_bg")

Browser/NUI fallback handling

NUI integrations should try the primary image first, then each fallback URL in order. Use the first URL that successfully loads.

interface VehicleImageCandidates {
  image?: string | null;
  fallbacks?: string[];
}

const imageProbeCache = new Map<string, boolean>();

function probeImage(url: string): Promise<boolean> {
  const cached = imageProbeCache.get(url);
  if (cached !== undefined) return Promise.resolve(cached);

  return new Promise((resolve) => {
    const img = new Image();

    img.onload = () => {
      imageProbeCache.set(url, true);
      resolve(true);
    };

    img.onerror = () => {
      imageProbeCache.set(url, false);
      resolve(false);
    };

    img.src = url;
  });
}

export async function resolveVehicleImage(
  candidates: VehicleImageCandidates,
): Promise<string | null> {
  const urls = [candidates.image, ...(candidates.fallbacks ?? [])].filter(
    (url): url is string => typeof url === "string" && url.length > 0,
  );

  for (const url of urls) {
    if (await probeImage(url)) return url;
  }

  return null;
}

On this page