nextcloud / nextcloud/academy

Absolute internal links in module content 404 on the deployed site

Open
#64 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
2
Forks
1
Avg merge
1d 2h
Merged PRs (30d)
7

Description

The problem

Module content is rendered by ReactMarkdown with no custom a renderer, so a markdown link becomes a plain <a href>. next/link and basePath are never involved.

The site is deployed with basePath: '/academy' (next.config.ts, added in #57). So an absolute internal link in content:

[the setup module](/standalone/standalone-env-setup)

renders as href="/standalone/standalone-env-setup" and resolves to https://nextcloud.github.io/standalone/standalone-env-setup — outside the project path. 404.

Only in-app navigation written as JSX gets the prefix, because that uses next/link.

Nothing is broken right now

Verified: no content file currently uses an absolute internal link. grep '](/' content/*/*/*.md returns nothing. This is a trap rather than a live bug.

It has already changed how content was written once. In #61, php/beginner/1.md refers to the standalone environment-setup module twice, and both references were deliberately left as prose ("find it in the Standalone section on the course home screen") rather than made into links, specifically because of this.

Why it is worth fixing rather than documenting

It fails in the most confusing possible way: the link works in local development and breaks only once deployed, because next dev also serves under /academy but a mistyped absolute path is easy to miss locally, and nothing in CI checks link targets.

And it is configuration-dependent, which makes it worse. When academy.nextcloud.com lands, basePath and assetPrefix come out (see the note in next.config.ts). At that point absolute links would start working — so a link committed today and found broken could silently "fix itself" later, and one written after the switch would break if the custom domain were ever removed.

Options

  1. Give ReactMarkdown a custom a component that routes internal links through next/link, or prefixes them with basePath from next/config. Fixes it once, for all content, and makes the obvious thing work. Wants care with external links, anchors (#section) and mailto:.
  2. Document "use relative or absolute-URL links only" in AGENTS.md and accept prose cross-references. Cheapest, but relies on everyone remembering, and the failure is invisible until deploy.
  3. Check link targets in CI. Complements either of the above rather than replacing them — the new pull-request.yml (#62) would be the place.

Option 1 is the one that stops this recurring. Content authors should not have to know about basePath.

Context

Found while wiring up the standalone module in #61.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by locating the module-content component that renders ReactMarkdown, then read next.config.ts to confirm the deployed basePath. Use content///*.md and the existing absolute-link example as a reproduction, while checking the proposed handling for external links, anchors, and mailto:. Done means internal content links work under /academy without changing external-link behavior; pull-request.yml is the stated place for complementary CI checks.

Written by the indexing model from the issue text.

Assessment

Tech stack
next.js, react, typescript
Domain
frontend, web-dev
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.