Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistency in how image paths are handled between markdown links and img hrefs #6403

Closed
7 tasks done
dwmkerr opened this issue Jan 19, 2022 · 1 comment
Closed
7 tasks done
Labels
bug An error in the Docusaurus core causing instability or issues with its execution closed: working as intended This issue is intended behavior, there's no need to take any action.

Comments

@dwmkerr
Copy link

dwmkerr commented Jan 19, 2022

Have you read the Contributing Guidelines on issues?

Prerequisites

  • I'm using the latest version of Docusaurus.
  • I have tried the npm run clear or yarn clear command.
  • I have tried rm -rf node_modules yarn.lock package-lock.json and re-installing packages.
  • I have tried creating a repro with https://new.docusaurus.io.
  • I have read the console error message carefully (if applicable).

Description

(I'd be happy to work on this issue if someone can point me in the right direction to get started)

It could be argued this is not a bug, but it is certainly unintuitive behaviour that makes things a little harder to work with.

Consider a folder in docs that contains a markdown file and an image (this is a pattern that I think could be pretty comon - each docs page contains its own folder of images, i.e. co-locating images with their associated document, if they are specific to the document, rather than shared across the site):

docs
-> folder1
-> folder1/index.md
-> folder1/images/image.png

The following markdown snippet will correctly render the image:

![Alt Text](./images/image.png)

As this works. GitHub also correctly renders this in pull requests etc.

I think the user would expect that the following would also work:

<img alt="Alt Text" src="./images/image.png" width="480px" />

This form might be used if you want to control the style/width of an image. The snippet above also renders correctly in a GitHub markdown preview in a code change.

However, instead we have to use this form:

<img alt="Alt Text" src={require('./images/image.png').default} width="480px" />

This works - however it is unintuitive that this form has to be used given that the pure markdown version works with relative paths properly. It also means that typical markdown previewing tools (such as GitHub's own markdown renderer) fail to render the images. This just makes the process of working with images that are co-located with documents a bit more painful.

I love the tool - I'm migrating Effective Shell to Docusaurus at the moment - one of the reasons I prefer it to Hugo is that I don't have to use weird platform specific features (like relref in Hugo) - I can just use plain old markdown links. But this img behaviour is a little odd. I understand it's a low priority issue with a simple workaround, but feels like the entire tool would be a little more user friendly (especially for complex folder structures like mine) if it was possible to use plain old relative paths in img tags.

An example of this inconsistency (which also shows how GitHub fails to render the img tags properly) is at: https://github.com/dwmkerr/effective-shell/blob/main/effective-shell/docs/01-transitioning-to-the-shell/01-getting-started/index.md

Please see the sandbox at: https://codesandbox.io/s/serene-butterfly-fz6tk?file=/docs/image-issue/image-issue.md

Steps to reproduce

Please see above, or the code at:

Expected behavior

Image tags would be able to reference images using relative paths without any special treatment.

Actual behavior

Image tags that reference images in relative paths require us to use require - this fails to preview in many common markdown renderers - such as GitHub's own renderer, meaning we are more likely to make mistakes when using these paths.

Your environment

  • Public source code: https://github.com/dwmkerr/effective-shell - docusaurus version is in the subfolder effective-shell
  • Public site URL: https://effective-shell.com/effective-shell
  • Docusaurus version used: 2.0.0-beta.14
  • Environment name and version (e.g. Chrome 89, Node.js 16.4): Node v14.15.1, Chrome Version 97.0.4692.71 (Official Build) (x86_64)
  • Operating system and version (e.g. Ubuntu 20.04.2 LTS): macOS Catalina 10.15.7 (19H1615)

Reproducible demo

https://github.com/dwmkerr/effective-shell/tree/main/effective-shell

Self-service

  • I'd be willing to fix this bug myself.
@dwmkerr dwmkerr added bug An error in the Docusaurus core causing instability or issues with its execution status: needs triage This issue has not been triaged by maintainers labels Jan 19, 2022
@Josh-Cena
Copy link
Collaborator

Josh-Cena commented Jan 19, 2022

Hi! Image paths are specially handled in Markdown by converting them to require calls. We have included that in our docs: https://docusaurus.io/docs/next/markdown-features/assets#images This is to make the behavior more in line with how GitHub renders images.

If you want the same effect in JSX, you have to wrap your path in require() as well in order for webpack to handle it. You have already realized that.

<img alt="Alt Text" src={require("./images/image.png").default} width="480px" />

The relevant source code is here:

function toImageRequireNode(node: Image, imagePath: string, filePath: string) {
const jsxNode = node as Literal & Partial<Image>;
let relativeImagePath = posixPath(
path.relative(path.dirname(filePath), imagePath),
);
relativeImagePath = `./${relativeImagePath}`;
const parsedUrl = url.parse(node.url);
const hash = parsedUrl.hash ?? '';
const search = parsedUrl.search ?? '';
const alt = node.alt ? `alt={"${escapeHtml(node.alt)}"} ` : '';
const src = `require("${inlineMarkdownImageFileLoader}${
escapePath(relativeImagePath) + search
}").default${hash ? ` + '${hash}'` : ''}`;
const title = node.title ? ` title="${escapeHtml(node.title)}"` : '';
Object.keys(jsxNode).forEach(
(key) => delete jsxNode[key as keyof typeof jsxNode],
);
(jsxNode as Literal).type = 'jsx';
jsxNode.value = `<img ${alt}src={${src}}${title} />`;
}

Note that if you just want to add a width attribute, #6339 will probably fix it for you.

And thanks for bringing this up! This was not the first case someone got confused about our magic with Markdown processing. I will include a new doc section on this.

@Josh-Cena Josh-Cena added closed: working as intended This issue is intended behavior, there's no need to take any action. and removed bug An error in the Docusaurus core causing instability or issues with its execution status: needs triage This issue has not been triaged by maintainers labels Jan 19, 2022
@Josh-Cena Josh-Cena added the bug An error in the Docusaurus core causing instability or issues with its execution label Jan 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug An error in the Docusaurus core causing instability or issues with its execution closed: working as intended This issue is intended behavior, there's no need to take any action.
Projects
None yet
Development

No branches or pull requests

2 participants