vernak2539 / astro-rehype-relative-markdown-links

Rehype Plugin for Astro that allows for usage of relative links between markdown files
https://www.npmjs.com/package/astro-rehype-relative-markdown-links
12 stars 4 forks source link

proposal: consider alternate approach to path transformation #27

Open techfg opened 4 months ago

techfg commented 4 months ago

Astro treats everything within a content collection as relative to the content collection, not the site itself. This enables site developers to do some pretty cool stuff with content collections (e.g., map a content collection posts to a url scheme of /blog/:year/:month/:day/:slug or use that same collection and map it instead to /coolstuff/year-month-day/:slug.

Currently, this plugin transforms URLs to absolute paths including adding any optionally specified basePath. However, this actually is counter to the way that Astro itself handles content collections since they do everything relative.

Transforming to absolute paths leads to a few different issues (and some benefits). The crux of the issue is that this plugin makes an assumption that the physical content collection directory is in the actual URL to the page but often it is not.

Due to transforming to absolute paths, various issues arise:

  1. Support "base" config option
  2. feat: support mapping a content collection directory name to a site page path
  3. bug: Content collection path segment is slugified
  4. When contentPath is the same as the collectionPath, some transformed paths are incorrect

This raises the question - should this plugin resolve to relative paths instead of absolute paths when transforming urls? The benefits of this would be:

1) We only need to know the content dir 2) We never have to know the collection name and can safely assume its directory is always the subdir immediately under content dir since that is what Astro requires. 3) A collection can be served from any virtual path and utilize file reference links and will work. For example, a content collection at src/content/posts could be served by src/pages/newsletter & src/pages/blog and work for both.

POC: https://stackblitz.com/edit/github-pdzrjo-th5yry

The above POC is a very crude approach to making this work and the modifications to the code necessary are rather trivial. In fact, both absolute and relative url resolution could be supported - although my thinking is that it should only be one of these modes for v1.

How to use:

  1. Go to https://stackblitz.com/edit/github-pdzrjo-th5yry?file=astro.config.mjs to open
  2. In the file, you'll see line 10 has a new option urlMode which was added for this POC. The possible values are relative and absolute (default: absolute). Depending on the mode configured here, the corresponding url format will be generated.
  3. Set the value to absolute and from the home page, click Blog -> 2023 -> January 15 link
  4. Try to click any of the links (there are 4) and they will all 404 because they were transformed to /posts/:slug instead of /blog/:slug because the content collection is in the posts directory but the page is served from /blog.
  5. Go back to Site Index and click My Blog -> 2023 -> January 15 link
  6. Same issue as Step 4
  7. Stay on the current web page and change the urlMode to relative in astro.config.mjs
  8. Check the links again - they work and correctly reference /my-blog/:slug
  9. Inspect the HTML and you'll see relative links (../../2023/01/15-sample-post)
  10. Bounce around anywhere you like, all the /pages (e.g., /blog, /my-blog, /your-blog) will work now when previously, none of them worked.

Again, this is just a POC but we've discovered many things in/around resolving the "real" content collection name when really, from a URL persective, the content collection physical directory name doesn't matter and could result in incorrect url transformation - it's the page path that matters and unfortunately, we have no way to know that value. This is a primary reason why, I believe, Astro itself uses relatively pathing within a content collection, since it never knows what the URL itself will be.

At the end of the day, I think going with absolute or relative pathing works and covers A LOT of ground currently not covered by Astro, the main question is prior to a v1, what direction makes the most sense and is most portable. If we go absolute, then I think the documentation should reflect the fact that page paths must map 1:1 to physical content collection paths (e.g., /blog/2024/05/01/post must correspond to src/content/blog/2024/05/01/post.md). If we go relative, there are some scenarios beyond what this POC handles that need to be covered but I think they can be done which would allow for not requiring physical dirs to page paths in a 1:1 configuration. Either way, there is still the question raised in #26 to be answered.

Additional Information

As mentioned, the code changes for this POC are very crude but demonstrate the intended outcome. They are based on the code that exists in PR #21. The changes were made to the following files and are rather minor - each change segmented with the following:

/* PROPOSED CODE START */
// ....
/* PROPOSED CODE END */
  1. https://stackblitz.com/edit/github-pdzrjo-th5yry?file=astro.config.mjs,plugin%2Fsrc%2Findex.d.ts%3AL8
  2. https://stackblitz.com/edit/github-pdzrjo-th5yry?file=astro.config.mjs,plugin%2Fsrc%2Futils.mjs%3AL104
  3. https://stackblitz.com/edit/github-pdzrjo-th5yry?file=astro.config.mjs,plugin%2Fsrc%2Findex.mjs%3AL30
  4. https://stackblitz.com/edit/github-pdzrjo-th5yry?file=astro.config.mjs,plugin%2Fsrc%2Findex.mjs%3AL86

Thoughts?

techfg commented 4 months ago

FYI - Edited How to use section Step 2 since I changed the structure of the file but forgot to update this section to correspond.

techfg commented 4 months ago

Created an updated version of the original POC using the code from #52. See the "Notes" on the Site Index page for information about how to adjust the behavior based on the collectionBase property.