Astro presentation


Astro Slide
Last updated on

Astro presentation proposal

Background

Last year, I begin to use marp to create slides for my presentations. The advantage of use marp is that I can write markdown and generate slides with it.

I also came across typst with its packages such as touying which can also be used to create presentations, i used it a couple of slides, it is a awesome tool.

both markdown and typst are in text format, and can be stored in git with version control, so we can track the changes of slides easily than powerponit files.

though both of them are not flexible as powerpoint, and don’t support multimedia like audio and video, but it is enough for me to create slides for most scenario. so i also want to integrate them into my blog, then i can share my slides with others, or present it online.

Astro integration with Marp

atro this is the framework i used to build my website, it leverage markdown or mdx file to create the content, which is perfect for me.

but astro don’t have marp plugin itself, so we need to develop it by ourself.

i also created an feature requet Integrate Marp with Astro for marp team.

updates

Today(2025/4/30), I initially implemented the astro-marp integration, not perfect but usable. my approach is to use marp-cli to convert the slide into html and save to dist/slide

the full code:

---
import { type CollectionEntry, getCollection } from "astro:content";
import createSlug from "../../lib/createSlug";
import type { SlideSchema } from "src/content/config";
import type {
marpCli,
CLIError as CLIErrorType,
CLIErrorCode as CLIErrorCodeType,
} from "@marp-team/marp-cli";
import path from "path";
import { readFileSync } from "fs";
export async function getStaticPaths() {
const slideEntries = await getCollection("slide");
return slideEntries.map((slideEntry) => ({
params: { slug: createSlug(slideEntry.data.title, slideEntry.slug) },
props: { slideEntry },
}));
}
interface Props {
slideEntry: CollectionEntry<"slide">;
}
const { slideEntry } = Astro.props;
const slide: SlideSchema = slideEntry.data;
const { marpCli } = await import("@marp-team/marp-cli");
const marpGeneratedFile = path.join(
"dist/slide",
createSlug(slide.title, slideEntry.slug),
"index.html",
);
if (slideEntry.filePath) {
try {
await marpCli([
"--allow-local-files",
"--html true",
"--theme",
"./src/styles/marp/" + slide.theme + ".scss",
slideEntry.filePath,
"-o",
marpGeneratedFile,
]);
} catch (e) {
console.error(e);
throw e;
}
}
const marpGeneratedFileContent = readFileSync(marpGeneratedFile, "utf-8");
---
<html lang="en" set:html={marpGeneratedFileContent} />

in the meanwhile, i enabled cloudflare R2 to host the images, athough astro already process the slide images locally, but i don’t know how to replace the post-processed images after marp-cli execution, so i instead use online images

  • improvement
    • can’t live preview the slide, any updates should be built firstly to the result
    • astro has already processed the images the slide referenced and saved to dist/_astro, but I don’t find proper way to get the post-processed images, and replace the href link in the post-marp html with these images files
    • don’t have an approach to utilize the plugin rehypeMermaid which can directly process mermaid graph
  • plan
    • may be create a rehypeMarp plugin to process the marp slide ??

Reference

Astro integration with typst

I found a new package astro-typst, it is An Astro Integration that lets you render Typst within Astro. it is in active development, so i will try this way to build the presentation, then i can write the presentation in typst document. according to the author of astro-typst, there still some obstacles that should be resolve to make it possible.

update: on 2025-05-08, I added this integration to the website, it worked. add a sidebar book where all typst documents are located

also after add typst integration, the cloudflare page build will exhaust with resource, so fallback to use github action to deploy the website to cloudflare pages

© 2025 Jennings Liu. All rights reserved.