Repository: facebook/docusaurus
File: packages/docusaurus-mdx-loader/src/remark/transformImage/index.ts (TypeScript)

Code before:
    return imageFilePath;
  } else {
    // relative paths are resolved against the source file's folder
    const imageFilePath = path.join(path.dirname(filePath), originalImagePath);
    if (!(await fs.pathExists(imageFilePath))) {
      return null;
    }
    return imageFilePath;
  }
}

async function processImageNode(target: Target, context: Context) {
  const [node] = target;

  if (!node.url) {
    node.url =
      context.onBrokenMarkdownImages({
        url: node.url,
        sourceFilePath: context.filePath,
        node,
      }) ?? node.url;
    return;
  }

  const parsedUrl = parseURLOrPath(node.url);
  if (parsedUrl.protocol || !parsedUrl.pathname) {
    // pathname:// is an escape hatch, in case user does not want her images to
    // be converted to require calls going through webpack loader
    if (parsedUrl.protocol === 'pathname:') {
      node.url = node.url.replace('pathname://', '');
    }
    return;
  }

  // We decode it first because Node Url.pathname is always encoded
  // while the image file-system path are not.
  // See https://github.com/facebook/docusaurus/discussions/10720
  const decodedPathname = decodeURIComponent(parsedUrl.pathname);

  // We try to convert image urls without protocol to images with require calls
  // going through webpack ensures that image assets exist at build time
  const localImagePath = await getLocalImageAbsolutePath(
    decodedPathname,
    context,
  );
  if (localImagePath === null) {
    node.url =
      context.onBrokenMarkdownImages({
        url: node.url,
        sourceFilePath: context.filePath,
        node,

Review comment (suggestion):
The condition `!parsedUrl.pathname` is now effectively dead code. The modern `URL` object returned by `parseURLOrPath()` always has a non-empty `pathname` property (minimum value is `/`), unlike the deprecated `url.parse()` which could return null/undefined. Consider removing this part of the condition since `parsedUrl.protocol` alone is sufficient to filter out URLs with protocols. Alternatively, add a comment explaining this is a defensive check for future-proofing.
```suggestion
  if (parsedUrl.protocol) {
```

Code after:
    }
    return imageFilePath;
  } else {
    // relative paths are resolved against the source file's folder
    const imageFilePath = path.join(path.dirname(filePath), originalImagePath);
    if (!(await fs.pathExists(imageFilePath))) {
      return null;
    }
    return imageFilePath;
  }
}

async function processImageNode(target: Target, context: Context) {
  const [node] = target;

  if (!node.url) {
    node.url =
      context.onBrokenMarkdownImages({
        url: node.url,
        sourceFilePath: context.filePath,
        node,
      }) ?? node.url;
    return;
  }

  const localUrlPath = parseLocalURLPath(node.url);
  if (!localUrlPath) {
    // pathname:// is an escape hatch, in case the user does not want images to
    // be converted to require calls going through webpack loader
    if (parseURLOrPath(node.url).protocol === 'pathname:') {
      node.url = node.url.replace('pathname://', '');
    }
    return;
  }

  // We decode it first because Node Url.pathname is always encoded
  // while the image file-system path are not.
  // See https://github.com/facebook/docusaurus/discussions/10720
  const decodedPathname = decodeURIComponent(localUrlPath.pathname);

  // We try to convert image urls without protocol to images with require calls
  // going through webpack ensures that image assets exist at build time
  const localImagePath = await getLocalImageAbsolutePath(
    decodedPathname,
    context,
  );
  if (localImagePath === null) {
    node.url =
      context.onBrokenMarkdownImages({
        url: node.url,
        sourceFilePath: context.filePath,