diff --git a/src/index.d.ts b/src/index.d.ts
index 3df82a2..4ce7d5a 100644
--- a/src/index.d.ts
+++ b/src/index.d.ts
@@ -1,7 +1,31 @@
export type TrailingSlash = 'always' | 'never' | 'ignore';
+type CollectionPathMode = 'subdirectory' | `root`
+
export interface Options {
contentPath?: string; // where you store your content relative to the root directory
+ /**
+ * @docs
+ * @name collectionPathMode
+ * @type {CollectionPathMode}
+ * @default `'subdirectory'`
+ * @description
+ *
+ * Where you store your collections:
+ * - `'subdirectory'` - Subdirectories under `contentPath` (ex: "src/content/docs/index.md" where docs is the content collection subdirectory of the contentPath src/content)
+ * - `'root'` - Directly inside `contentPath` (ex. src/content/index.md where src/content is the contentPath)
+ *
+ * Use the `root` configuration option when you are treating a single content collection as if it where located in the site root. In most scenarios, you should set this
+ * value to `subdirectory` or not set this value and the default of `subdirectory` will be used.
+ *
+ * ```js
+ * {
+ * // Example: Use `subdirectory` mode
+ * collectionPathMode: `subdirectory`
+ * }
+ * ```
+ */
+ collectionPathMode?: CollectionPathMode;
basePath?: string; // https://docs.astro.build/en/reference/configuration-reference/#base
/**
* @name trailingSlash
diff --git a/src/index.mjs b/src/index.mjs
index 2b64d48..e849fb0 100644
--- a/src/index.mjs
+++ b/src/index.mjs
@@ -23,6 +23,9 @@ const defaultContentPath = ["src", "content"].join(path.sep);
/** @type {import("./index").TrailingSlash} */
const defaultTrailingSlash = 'ignore';
+/** @type {import("./index").CollectionPathMode} */
+const defaultCollectionPathMode = 'subdirectory';
+
/** @param {import('./index').Options} options */
function astroRehypeRelativeMarkdownLinks(options = {}) {
return (tree, file) => {
@@ -57,9 +60,9 @@ function astroRehypeRelativeMarkdownLinks(options = {}) {
const { data: frontmatter } = matter(relativeFileContent);
const frontmatterSlug = frontmatter.slug;
const contentDir = options.contentPath || defaultContentPath;
-
+ const collectionPathMode = options.collectionPathMode || defaultCollectionPathMode;
const relativeToContentPath = path.relative(contentDir, relativeFile);
- const collectionName = path.dirname(relativeToContentPath).split(path.posix.sep)[0];
+ const collectionName = collectionPathMode === 'root' ? "" : path.dirname(relativeToContentPath).split(path.posix.sep)[0];
const relativeToCollectionPath = path.relative(collectionName, relativeToContentPath);
const withoutFileExt = replaceExt(relativeToCollectionPath, "")
const pathSegments = withoutFileExt.split(path.posix.sep);
@@ -67,9 +70,9 @@ function astroRehypeRelativeMarkdownLinks(options = {}) {
const resolvedSlug = resolveSlug(generatedSlug, frontmatterSlug);
const trailingSlashMode = options.trailingSlash || defaultTrailingSlash;
- const resolvedUrl = path.posix.sep +
+ const resolvedUrl =
[
- collectionName,
+ !collectionName ? '' : (path.posix.sep + collectionName),
resolvedSlug,
].join(path.posix.sep);
diff --git a/src/index.test.mjs b/src/index.test.mjs
index 8ee41b4..3d4ff65 100644
--- a/src/index.test.mjs
+++ b/src/index.test.mjs
@@ -303,7 +303,7 @@ test("astroRehypeRelativeMarkdownLinks", async (t) => {
const input = 'foo';
const { value: actual } = await rehype()
.use(testSetupRehype)
- .use(astroRehypeRelativeMarkdownLinks, { contentPath: "src/fixtures" })
+ .use(astroRehypeRelativeMarkdownLinks, { contentPath: "src/fixtures", collectionPathMode: 'root' })
.process(input);
const expected =
@@ -319,7 +319,7 @@ test("astroRehypeRelativeMarkdownLinks", async (t) => {
const input = 'foo';
const { value: actual } = await rehype()
.use(testSetupRehype)
- .use(astroRehypeRelativeMarkdownLinks, { contentPath: "src/fixtures/dir-test-custom-slug" })
+ .use(astroRehypeRelativeMarkdownLinks, { contentPath: "src/fixtures/dir-test-custom-slug", collectionPathMode: 'root' })
.process(input);
const expected =
@@ -335,7 +335,7 @@ test("astroRehypeRelativeMarkdownLinks", async (t) => {
const input = 'foo';
const { value: actual } = await rehype()
.use(testSetupRehype)
- .use(astroRehypeRelativeMarkdownLinks, { contentPath: "src/fixtures" })
+ .use(astroRehypeRelativeMarkdownLinks, { contentPath: "src/fixtures", collectionPathMode: 'root' })
.process(input);
const expected =
@@ -351,7 +351,7 @@ test("astroRehypeRelativeMarkdownLinks", async (t) => {
const input = 'foo';
const { value: actual } = await rehype()
.use(testSetupRehype)
- .use(astroRehypeRelativeMarkdownLinks, { contentPath: "src/fixtures" })
+ .use(astroRehypeRelativeMarkdownLinks, { contentPath: "src/fixtures", collectionPathMode: 'root' })
.process(input);
const expected =
@@ -367,7 +367,7 @@ test("astroRehypeRelativeMarkdownLinks", async (t) => {
const input = 'foo';
const { value: actual } = await rehype()
.use(testSetupRehype)
- .use(astroRehypeRelativeMarkdownLinks, { contentPath: "src/fixtures" })
+ .use(astroRehypeRelativeMarkdownLinks, { contentPath: "src/fixtures", collectionPathMode: 'root' })
.process(input);
const expected =
@@ -383,7 +383,7 @@ test("astroRehypeRelativeMarkdownLinks", async (t) => {
const input = 'foo';
const { value: actual } = await rehype()
.use(testSetupRehype)
- .use(astroRehypeRelativeMarkdownLinks, { contentPath: "src/fixtures" })
+ .use(astroRehypeRelativeMarkdownLinks, { contentPath: "src/fixtures", collectionPathMode: 'root' })
.process(input);
const expected =
@@ -399,7 +399,7 @@ test("astroRehypeRelativeMarkdownLinks", async (t) => {
const input = 'foo';
const { value: actual } = await rehype()
.use(testSetupRehype)
- .use(astroRehypeRelativeMarkdownLinks, { contentPath: "src/fixtures" })
+ .use(astroRehypeRelativeMarkdownLinks, { contentPath: "src/fixtures", collectionPathMode: 'root' })
.process(input);
const expected =