Skip to content

Conversation

Its-Just-Nans
Copy link
Contributor

@Its-Just-Nans Its-Just-Nans commented Aug 15, 2025

If you use mise, do normal workflows like the website.yml

mise run generate-docs
mise run generate-web

if not using mise

cargo run --package typst-docs -- --assets-dir assets/docs --out-file assets/docs.json --base /
cd website/
npm install
npm run build
cd ..

In both case to view result

# view result
cd website/dist && python -m http.server

@Its-Just-Nans
Copy link
Contributor Author

@YDX-2147483647 You may be interested on this one too

Related to
#266 (comment)

@3w36zj6 3w36zj6 requested review from 3w36zj6 and Copilot August 16, 2025 03:29
Copilot

This comment was marked as outdated.

@3w36zj6
Copy link
Member

3w36zj6 commented Aug 16, 2025

@Its-Just-Nans

I think it's a good idea to rename this repository from typst-jp.github.io to docs. @typst-jp is planning to host multiple contents in the future, such as Japanese translations of Typst Universe and original guides (like typst-doc-cn/tutorial), so this would help maintain everything under a consistent naming convention. The new typst-jp.github.io can simply host the organization's landing page.

What do you think? @mkpoli @kimushun1101 @ultimatile @gomazarashi @YDX-2147483647

If we go with this approach, Hono SSG needs to support settings that treat subdirectories as the root. As long as typst-docs and Hono SSG have the same base URL settings, everything should continue to be hosted correctly.

@YDX-2147483647
Copy link
Contributor

YDX-2147483647 commented Aug 16, 2025

As long as typst-docs and Hono SSG have the same base URL settings, everything should continue to be hosted correctly.

It might not be that simple.
For example, both typst-jp and the official typst.app put the rendered PNGs outside of /docs/ at present:

publicAssetsDocsPath should be changed to ./public/docs/assets/ or similar things.

const publicAssetsDocsPath = resolve(__dirname, "./public/assets/docs/");

This is a picayune, but my point is that a painful period of transition would be inevitable. It is best to announce the plan ont the website before taking any actions.

For reference, typstyle had changed the URL of its playground twice previously without any notice or redirection. The experience was very bad.

@Its-Just-Nans
Copy link
Contributor Author

Its-Just-Nans commented Aug 16, 2025

Yes

This is why I ended up using a subdomain typst-github-io.n4n5.dev instead of n4n5.dev/typst-github-io/

This repo https://github.com/typst-jp/typst-jp.github.io has a / access so it's fine in this case.

But if a repo like https://github.com/typst-community/docs/ will be created, it will have access to https://typst.community/docs then yes some work will need to be done.

The other option is to create https://docs.typst.community/

@3w36zj6
Copy link
Member

3w36zj6 commented Aug 16, 2025

On GitHub Pages, the docs/ subdirectory of the typst-jp/typst-jp.github.io repository and the root directory of the typst-jp/docs repository will resolve to the same URL, so there’s no issue. The output location for asset files can also be changed as needed, so that’s not a problem either.

@Its-Just-Nans
Copy link
Contributor Author

Its-Just-Nans commented Aug 16, 2025

On GitHub Pages, the docs/ subdirectory of the typst-jp/typst-jp.github.io repository and the root directory of the typst-jp/docs repository will resolve to the same URL, so there’s no issue.

Yes, but I think we will need to change /docs to / or the website will be at /docs/docs/

@3w36zj6
Copy link
Member

3w36zj6 commented Aug 17, 2025

I have created a repository for experimental purposes:

https://github.com/typst-jp/docs

(This will be deleted before the official migration in order to make redirection from the current repository work.)

Currently, the contents of this repository are deployed at https://typst-jp.github.io/docs/. Although there are still some tasks left, such as supporting sitemap and robots.txt, I believe you can confirm that CSS, fonts, assets, and routing are working correctly.

Please note the following points:

First, the assets generated by the typst-docs CLI are expected to be located at ${base_url}/assets/*. For this reason, it was necessary to align the delivery method on the SSG side as well. Fonts and favicon were moved to the root directory to avoid conflicts.

https://github.com/typst-jp/typst-jp.github.io/blob/739d975e8b54c1c65158be1b242ee6809378d411/docs/src/main.rs#L88-L96

Next, in the routing definition of Hono, the base path specified by the typst-docs CLI is removed.

With these changes, I believe the migration can be completed. What do you think?

@YDX-2147483647 @Its-Just-Nans

Note: The build works, but currently the dev server does not run.

@Its-Just-Nans
Copy link
Contributor Author

Hi

I have two questions:

@3w36zj6
Copy link
Member

3w36zj6 commented Aug 17, 2025

Oh, I forgot about Pagefind, so I'll make sure to address that as well.

This repository and the feature branch are intended for minimal changes to experiment with GitHub Pages deployment. The responsibility of this feature branch is to set up configuration for subdirectory deployment, not to split out the SSG project into a separate repository. So, handling that is out of scope for this branch.

cf. #271 (comment)

(This will be deleted before the official migration in order to make redirection from the current repository work.)

Please note that even after the current repository is renamed to typst-jp/docs, the SSG core itself will not be managed there. Instead, it will likely have a more appropriate repository name.

@Its-Just-Nans
Copy link
Contributor Author

Okay great, nice job on the docs/ repo

Just for info, maybe the docs will be on a subdomain instead of a subfolder

https://discord.com/channels/1054443721975922748/1194684809906237500/1406358626741911724

This is just a little tweak

@3w36zj6
Copy link
Member

3w36zj6 commented Aug 17, 2025

Remaining tasks:

  • Make the dev server work
  • Get Pagefind working
  • Allow Sitemap and robots only when deploying to the root directory

@3w36zj6 3w36zj6 changed the title remove /docs chore: support configuration for deployment to custom base path Aug 17, 2025
@Its-Just-Nans
Copy link
Contributor Author

Its-Just-Nans commented Aug 17, 2025

I think it's ready for review ^^

For information my commit bf34eb6

  • fix the dev server to correclty handle the public folder (maybe there is a better way?)
  • clearly disabling the pagefin on DEV mode

But I see that we still have a 404

image

Copy link
Member

@3w36zj6 3w36zj6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’ve confirmed that it works. There are almost no issues.

@Its-Just-Nans
Copy link
Contributor Author

Hi

For now, I am waiting on some update about honojs/vite-plugins#286 :)

If this is merged, some code will need rework/deletion
For example

  • the hono basePath
    const app = new Hono().basePath(import.meta.env.DEV ? basePath : "/");
    
  • the code for serveStatic

// Remove trailing slash from base.
const baseClean = basePath !== "/" ? basePath.replace(/\/+$/, "") : basePath;
// Remove leading slash from path.
const pathClean = path.replace(/^\/+/, "");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should path really be cleaned?

  • Here: ./index.htmlindex.html = /index.html.
  • URL API: ./index.html = index.html/index.html.
Test code
>> new URL('./index.html', 'https://example.com/sub/').href
"https://example.com/sub/index.html"
>> new URL('index.html', 'https://example.com/sub/').href
"https://example.com/sub/index.html"
>> new URL('/index.html', 'https://example.com/sub/').href
"https://example.com/index.html" 

>> new URL('./index.html', 'https://example.com/sub/file').href
"https://example.com/sub/index.html"
>> new URL('index.html', 'https://example.com/sub/file').href
"https://example.com/sub/index.html"
>> new URL('/index.html', 'https://example.com/sub/file').href
"https://example.com/index.html" 

Url::join in rust behaves the same.
(That crate is based on the URL Standard. However, I didn't check the real URL Standard because it's too hard to understand.)

If this part is modified, then vite.config.ts also needs an update.

- joinPath(basePath, "@")
- joinPath(basePath, "node_modules")
+ joinPath(basePath, "/@")
+ joinPath(basePath, "/node_modules")

* applyBasePath("/foo/bar", "baz/qux") -> "baz/qux"
* ```
*/
export const applyBasePath = (basePath: string, path: string): string => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that applyBasePath is not actually used?

if (!route.startsWith(basePath)) return route;
const offset = basePath.length - (basePath.endsWith("/") ? 1 : 0);
return route.slice(offset);
};
Copy link
Contributor

@YDX-2147483647 YDX-2147483647 Aug 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For reference, the following is the implementation of related functions in vite.

Codes

https://github.com/vitejs/vite/blob/84079a84ad94de4c1ef4f1bdb2ab448ff2c01196/packages/vite/src/node/plugins/asset.ts#L334-L335

export async function fileToDevUrl(...) {
  ...
  const base = joinUrlSegments(config.server.origin ?? '', config.decodedBase)
  return joinUrlSegments(base, removeLeadingSlash(rtn))
}

https://github.com/vitejs/vite/blob/84079a84ad94de4c1ef4f1bdb2ab448ff2c01196/packages/vite/src/node/utils.ts#L1460-L1471

export function joinUrlSegments(a: string, b: string): string {
  if (!a || !b) {
    return a || b || ''
  }
  if (a.endsWith('/')) {
    a = a.substring(0, a.length - 1)
  }
  if (b[0] !== '/') {
    b = '/' + b
  }
  return a + b
}

https://github.com/vitejs/vite/blob/84079a84ad94de4c1ef4f1bdb2ab448ff2c01196/packages/vite/src/node/utils.ts#L1477-L1483

export function stripBase(path: string, base: string): string {
  if (path === base) {
    return '/'
  }
  const devBase = withTrailingSlash(base)
  return path.startsWith(devBase) ? path.slice(devBase.length - 1) : path
}

https://github.com/vitejs/vite/blob/84079a84ad94de4c1ef4f1bdb2ab448ff2c01196/packages/vite/src/shared/utils.ts#L48-L53

export function withTrailingSlash(path: string): string {
  if (path[path.length - 1] !== '/') {
    return `${path}/`
  }
  return path
}

* @example
* ```ts
* joinPath("/base/", "/foo") -> "/base/foo"
* joinPath("/base", "foo") -> "/base/foo"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

basePath will be passed to vite config.
I don't know if the current behavior is consistent with vite…

I thought vite accepts a base path if and only if it starts and ends with a slash (/ or /base/).
But its doc says https://bar.com/foo/, ./, and "" (empty string) are also acceptable.
As for /base (without a trailing slash), what will happen is not mentioned.

Have all possibilities been tested?
If not, perhaps add a note here or in metadata.ts?

Only /, /base/, /sub/folder/, etc. are recommended and other variants might be inconsistent with vite.

<script>
import("${joinPath(basePath, "/@vite/client")}")
</script>
`}
</head>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@YDX-2147483647
Copy link
Contributor

YDX-2147483647 commented Aug 20, 2025

Good work!

I confirm that path handling is fine when base is /docs/ or /sub/f/.
path.ts is heavily tested, but I'm not quite sure about all the test cases.
I mean of course path.ts is consistent with path.test.ts, but when actually used in combination with hono jsx and vite, there may still be unforeseen problems.
I'm not really suggesting any changes in path.ts. Just record it for future debugging, "this part may not be as reliable as the others."

Another issue is that a hard-coded URL was missed. See #271 (comment).

@3w36zj6
Copy link
Member

3w36zj6 commented Aug 22, 2025

I have rewritten the path utility. Relative paths are not considered at this time. Hardcoded logic has been removed, and the value of the base path is now respected.
Also, the base path type definition now enforces a leading and trailing slash.

@3w36zj6 3w36zj6 requested a review from YDX-2147483647 August 22, 2025 01:27
Copy link
Contributor

@YDX-2147483647 YDX-2147483647 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better, but there're still small bugs:

  • 原文(英語)を開く is broken in a different way
  • basePath starts and ends with a slash, but these two might be the same slash

if (parts[0].startsWith("/")) {
needsLeadingSlash = true;
} else if (parts[0] === "") {
if (firstNonEmpty?.startsWith("/")) needsLeadingSlash = true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (firstNonEmpty?.startsWith("/")) needsLeadingSlash = true;
if (firstNonEmpty.startsWith("/")) needsLeadingSlash = true;

Comment on lines +52 to +55
const typstOfficialRouteUrl = joinPath(
typstOfficialDocsUrl,
removeBasePath(basePath, route),
);
Copy link
Contributor

@YDX-2147483647 YDX-2147483647 Aug 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const typstOfficialRouteUrl = joinPath(
typstOfficialDocsUrl,
removeBasePath(basePath, route),
);
const typstOfficialRouteUrl = new URL(
removeBasePath(basePath, route).replace(/^\//, ""),
typstOfficialDocsUrl,
).toString();

Otherwise, it will become https:/typst.app/docs/reference/context/, where https:// is transformed into https:/.

In my browser, that URL is interpreted as http://localhost:4173/typst.app/docs/reference/context/, though I don't know why…

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added handling for paths starting with http(s)://. 89b8576

export const typstOfficialUrl = "https://typst.app";
/** The official Typst documentation base URL. */
export const typstOfficialDocsUrl = "https://typst.app/docs";
Copy link
Contributor

@YDX-2147483647 YDX-2147483647 Aug 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
export const typstOfficialDocsUrl = "https://typst.app/docs";
export const typstOfficialDocsUrl: `https://${string}/` =
"https://typst.app/docs/";

The trailing slash will affect the result of the URL API.

>> new URL('a','https://typst.app/docs/').href
"https://typst.app/docs/a"
>> new URL('a','https://typst.app/docs').href
"https://typst.app/a" 

See #271 (comment)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good suggestion. HTTP is now also allowed, considering local environments.

Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds support for configuration to deploy the website to a custom base path (specifically /docs/) instead of the root path. This enables the documentation site to be deployed as a subdirectory while maintaining proper URL generation and routing.

  • Updates the build configuration to support a configurable base path (/docs/)
  • Implements path manipulation utilities for joining and removing base paths
  • Modifies routing, asset loading, and URL generation to respect the configured base path

Reviewed Changes

Copilot reviewed 17 out of 27 changed files in this pull request and generated no comments.

Show a summary per file
File Description
website/vite.config.ts Updates Vite configuration to use configurable base path and adjusts SSG plugins accordingly
website/src/utils/path.ts Adds utility functions for joining URL paths and removing base paths
website/src/utils/path.test.ts Comprehensive test suite for path utility functions
website/src/metadata.ts Introduces basePath configuration and separates origin URL from base path
website/src/index.tsx Updates routing logic to handle base path removal and adds static file serving for dev mode
website/src/globals.css Updates font asset URLs to remove /assets/ prefix
website/src/components/ui/type2href.ts Adds trailing slashes to generated type reference URLs
website/src/components/ui/common/SiteTitle.tsx Updates home link to use configured base path
website/src/components/ui/common/SearchWindow.tsx Conditionally loads search assets with proper base path in production
website/src/components/ui/common/Breadcrumbs.tsx Updates breadcrumb home link to use base path
website/src/components/ui/FunctionParameters.tsx Updates type reference links to include base path
website/src/components/ui/FunctionDefinition.tsx Updates type reference links to include base path
website/src/components/templates/BaseTemplate.tsx Updates all asset URLs and links to respect base path configuration
website/public/index.html Removes redirect HTML file (no longer needed)
website/package.json Updates dependencies and adjusts search indexing glob pattern
website/.gitignore Updates ignored paths to reflect new asset structure
.mise.toml Updates task configuration to use new base path parameter

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Copy link
Contributor

@YDX-2147483647 YDX-2147483647 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Finally there's no problem! 🎉


Update: There exist hard-coded origin and base path in markdown/rust files, and this PR will not handle them. However, I think it's acceptable.

| documentation | ドキュメント | [公式ドキュメント](https://typst.app/docs)[日本語ドキュメント](https://typst-jp.github.io/docs/)など |

Copy link
Member

@3w36zj6 3w36zj6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks to @Its-Just-Nans and @YDX-2147483647, we've made significant progress. I appreciate your hard work.

@3w36zj6
Copy link
Member

3w36zj6 commented Aug 23, 2025

There exist hard-coded origin and base path in markdown/rust files, and this PR will not handle them. However, I think it's acceptable.

Please note that the SSG and the documentation are loosely coupled and depend only on docs.json.

Indeed, it would be convenient if the metadata configuration file for the SSG could also be handled by typst-docs.

@3w36zj6 3w36zj6 merged commit 7c5fc33 into typst-jp:main Aug 23, 2025
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants