withastro / astro

The web framework for content-driven websites. ⭐️ Star to support our work!
https://astro.build
Other
47.26k stars 2.51k forks source link

Link Resolution in `index.md` files #5680

Closed lorenzolewis closed 1 year ago

lorenzolewis commented 1 year ago

What version of astro are you using?

1.7.2

Are you using an SSR adapter? If so, which one?

None

What package manager are you using?

npm

What operating system are you using?

Mac

Describe the Bug

When linking to relative sources (either other markdown files via the []() syntax or assets via the ![]() syntax, although images are expected to not work) from a file specifically named index.md the resulting href's don't resolve properly.

The links are appearing to resolve one level up further than they are supposed to.

For example, a link in src/pages/api/subdir/index.md (URL being localhost:3000/api/subdir) that points to a sibling page in src/pages/api/subdir/app.md via a relative link [app](app) will incorrectly resolve to localhost:3000/api/app.

If I instead have a link in src/pages/api/subdir/page.md (URL being localhost:3000/api/subdir/page) that points to a sibling page in src/pages/api/subdir/app.md via a relative link [app](app) will correctly resolve to localhost:3000/api/subdir/app.

This similar issue can be seen with asset resolution in src/pages/image/subdir, although it is expected that relative assets have other issues. But you can still see how the src of those images have the same issue as links.

I'm willing to look into this for a bug fix if this is agreed to be a bug.

Link to Minimal Reproducible Example

https://stackblitz.com/github/lorenzolewis/astro-md-extension-issue?

Participation

matthewp commented 1 year ago

Astro does not modify links in markdown or mdx files. if you want to link to something the best bet is to use absolute URLs instead. This is definitely not ideal and we are working on some ideas to fix this. One possible solution in the meantime is to use a custom remark/rehype plugin to resolve the URLs for you. There might already be such a plugin in the ecosystem, I don't know.

My expectation is that you write ./foo that's exactly what should be in the output HTML. If you see differently that would be a bug. But from your stackblitz example the HTML is exactly as written, which is what is expected today.

Changing the behavior would be a breaking change and would have to happen in a major version change. We need a RFC first, however, which can be started on here: https://github.com/withastro/rfcs/discussions

matthewp commented 1 year ago

Closing as the stackblitz is expected behavior.

lorenzolewis commented 1 year ago

I agree that if I write ./foo then that's how it should be output in the HTML and is what's happening.

However, the way that files are generated is causing a side effect from my understanding.

For instance, I have the setup with these two source files, their generated HTML output, and their resulting URLs:

Source File Generated File Generated URL
/src/pages/index.md /dist/index.html http://localhost:3000
/src/pages/siblingpage.md /dist/siblingpage/index.html http://localhost:3000/siblingpage

I would expect links in the two source to resolve the same since they are sibling files regardless if one is named index or not (and this is how it works when browsing markdown files locally such as in VS Code).

Since the files have different output depths (i.e. index.md staying at the same level, siblingpage.md effectively moving down a level to siblingpage/index.html) this is different than how it's represented in Markdown and also different behaviour than markdown tools expect.


I guess this is more of a topic around what is Astro's expected role in Markdown transformations? Is it to be as hands-off as possible and not do any processing (so not modifying any links in this case), or is it to make markdown adapt to HTML output where they're a difference between the two formats (so including a transformation layer)?

Depending on that then I could take a stab at writing an RFC keeping in mind the respective feedback.

Thanks for the quick response by the way! :D

Edit: This would probably also impact https://github.com/withastro/astro/issues/5682 as well based on the direction

matthewp commented 1 year ago

@lorenzolewis I think what you are seeing is not about Astro but is about how browsers resolve URLs. Browsers do not know if something is a "folder" or not. So for it to resolve something like you would want a folder to resolve you need for it to have a / at the end. With Astro you can configure this with trailingSlash: 'always', but you need to remember to put the trailing slash in the links yourself.

I recommend playing around with new URL('./rel', 'http://example.com/subpath') in your console and seeing what it produces, because URL resolution is not 100% intuitive.

I guess this is more of a topic around what is Astro's expected role in Markdown transformations? Is it to be as hands-off as possible and not do any processing (so not modifying any links in this case), or is it to make markdown adapt to HTML output where they're a difference between the two formats (so including a transformation layer)?

The expectation for Astro is that it does not touch the HTML you write at all. So any sort of "magic" has to be opted-in. One possible solution a .astro file would be something like a directive: <a resolve:href="./path/to/another/page"></a> would turn that into an absolute URL. That's just one idea. But that wouldn't work in .md files of course.

So although we have taken the position that we do not modify your HTML, there is an argument to be made that we should in some cases, and relative links is one such case. So although I can't promise that an RFC about that would pass, it's worth discussing. Or any other sort of solutions you might come across.

lorenzolewis commented 1 year ago

Thanks, that makes sense. I might write up an RFC related to the new Content Collections as those might be a better use case for where expectations for "traditional markdown behaviour" might be more inline with that use case.

lorenzolewis commented 1 year ago

Relevant RFC discussion opened in https://github.com/withastro/rfcs/discussions/424

vernak2539 commented 1 year ago

Until this gets into Astro proper, I ended up writing a rehype plugin called astro-rehype-relative-markdown-links specifically for astro to do something like this in md and mdx files.

It's still a work in progress (only supports md and mdx relative paths)