Personal Website
3/2025 - current
Crafting a fast, reactive Multi-Page Application to host personal information and publish projects
Written by: Violet Monserate
![]()
One of piece of advise I—along with every other student in STEM—consistently recieve is to build a personal website and park all my projects onto there. With this in mind, I have made this website, but it’s not any ordinary website; I set myself some additional objectives:
-
Make it snappy: I am so sick of slow, ram-consuming websites that run thounds of lines of JavaScript, and wanted to return a more traditional form of web-development, focused more on quickly delivering information to users.
-
Make it accessible: I wanted to make sure that all elements of the website would be as universally usable as possible, by including good alt text in images, minimizing how much JavaScript is used, and following other aspects laid out by the Web Content Accessibility Guidelines (WCAG). In this point, I also wanted to be easily usable on a computer, tablet, phone, or otherwise.
-
Make it pretty: this was probably at the bottom of my list in terms of priority, but having a pretty website would give me more practice in doing proper web-development, and also feel better at showing it off to peers, recruiters, and whomever else.
Why Astro?
While doing research on the different frameworks that were possible, one stuck out to me: Astro. I have experience with a couple different frameworks, including React, but was not really satisfied with how slow Single Page Applications (SPA) can feel. In addition, the website HAS to be static, as I did not want to worry about setting up a whole server to dynamically serve content. As such, I sought out a simple, lightweight Multi Page Application (MPA) framework, and stumbled across Astro.
In short, Astro does a lot of pre-processing as it creates the many different HTML files that are hosted on the static server, condensing all of the JavaScript to really reduce the load that users have to endure. It also simplifies the SEO process and ensures that different pages of my website are easily searchable in any given Search Engine.
It also is just another web dev framework for me to learn, and pratice, and to generally improve as picking up new languages/frameworks.
GitHub Pages? Why not _____?
Another choice I made was to stick with GitHub Pages, as opposed to anything else, was because I already would be storing it on GitHub, and static website hosting is free on GitHub Pages, so might as well use it! It also has a lot of built in integration with GitHub repositories, allowing for automatic deployment when anything is pushed to the remote repository.
Cool Features
As I learned to make more and more components, I created a couple that I’m particularly happy with! There aren’t the only components, and you can see all of those in my GitHub repository.
Cards and Card Grid
To easily share the different projects I wanted brief overviews with thumbnails and icons that quickly share the information on all my projects. Following some principles I learned in CSE 440, I made sure to utilize whitespace to group each of the different projects together, and to give users continual feedback about what they’re clicking or hoving over by using shadows, for example. Even better, the card grid itself is responsive to the size of the viewport, increasing and the decreasing the number of cards appropriately.
If you are curious about how the code turned out, you can view the grid component here and the card component here. One of the additions that I hope to make in the near future is the ability to filter through the different projects, and look at ones with only specific tags.
Markdown Layout
To REALLY simplify the process of presenting all of the different projects I have my hands in, I created a .md layout file that not only maintains the general design and style of the entire website (with the same navigation, footer, and header), but also easily interfaces with SEO utilities, OpenGraph protocol, and more. The important information that would be used by cards or SEO utilities is included in the frontmatter in a very straightforward format that I can fill out without worrying about properly formatting HTML.
LaTeX
I was trying to utilize to show some equations, and that led to KaTeX, which renders math. By using another library, remark-math, I am simply able to write beautiful equations like
with some simple code, like so:
$$
\int_{0}^{\infty} \left( \sum_{n=1}^{\infty} \frac{\alpha_n}{n^2 + \beta^2} \right) \cdot \sqrt{\frac{\pi}{2}} \, dx = \lim_{x \to \infty} \left[ e^{-\gamma x^2} + \frac{\delta}{x^2} \right] + \text{constant}
$$
Or for inline things like , , or , we do $\Tau$, $\Beta$, or $\Kappa$.
You can look at the markdown layout component itself here.
Google Docs to Markdown
Much of my classwork already begins as a carefully written report in Google Docs. While it is a good environment for drafting, collaborating, and submitting assignments, the exported HTML is not a good format for this personal website (being a far different style). It includes generated classes, inline pixel dimensions, document-specific page layout, and presentation details that only make sense inside the original document. Copying that HTML directly into my website would make the page inherit the appearance of a school report, which isn’t exactly desireable.
I wanted a workflow where I could finish a report in Google Docs and then transfer that work to the website without rewriting the entire document by hand. The result is the google_docs_to_markdown.py translator. It takes the HTML export from Google Docs as input and produces a normal project Markdown file, such as fpga-music.md, together with the image assets needed by Astro. The converter is intentionally a translator rather than a browser-like HTML renderer; it keeps the content and useful structure while discarding the Google Docs-specific presentation layer.
The conversion process performs several jobs:
- It parses the exported HTML structurally, identifying paragraphs, headings, lists, links, code, and images instead of relying on fragile string replacements.
- It converts the document hierarchy into the site’s Markdown hierarchy. The page title is supplied by the project frontmatter, so report headings begin at
##rather than competing with the page’s#title. - It recognizes Google Docs’ generated styling classes for technical content. Inline green code becomes annotated Markdown such as
`asset_t{:system-verilog}`, while consecutive code lines become a single fencedsystem-verilogblock for Shiki syntax highlighting. - It turns italicized Google Docs figure descriptions into the image-caption convention used throughout the site: an image followed by an italicized caption. Images are kept outside the asterisks so the caption styling does not accidentally italicize the image itself.
- It copies referenced images into a project-specific Astro asset directory and creates a blank 1920x1080
fpga-music-editor-thumbnail.pngplaceholder in the generated frontmatter. I can then replace that file with a custom Canva design without having the converter make creative decisions about the project’s visual identity. - It generates the frontmatter needed by the project collection, including authors, dates, tags, descriptions, the hero image, and the technologies displayed on the project card.
The result is deliberately different from the Google Docs source. The report keeps its technical explanations, figures, code, and testing evidence, but the website supplies its own typography, spacing, navigation, responsive image sizing, figure captions, syntax highlighting, metadata, and overall visual identity. A class report can therefore remain recognizable as my work while feeling like part of the same portfolio as my software, robotics, and hardware projects.
The converter also leaves room for judgment. Google Docs exports do not reliably provide useful alternative text for diagrams, and they cannot know which image makes the best project thumbnail. The script marks missing image descriptions for review and creates a stable 1920x1080 placeholder for a manually designed thumbnail, while I make the final decisions about accessibility text, captions, metadata, and what should be public. This keeps the repetitive transfer work automated without pretending that document structure can replace editorial or accessibility review.
The converter is also reusable beyond this particular FPGA project. Its --help command documents options for changing the project title, code language, authors, dates, descriptions, tags, card icons, section, thumbnail filename, and source metadata behavior. The input argument is the Google Docs HTML export, the output argument is the Markdown or MDX file to generate, and --assets names the directory where the report’s images and thumbnail placeholder should be copied. For example:
python3 src/scripts/google_docs_to_markdown.py report.html \
src/pages/projects/report.md \
--assets src/assets/report \
--language python \
--title "Course Report"
By default, everything before the first document heading is discarded. This removes names, student IDs, course labels, and dates that Google Docs commonly places at the top of a report. --keep-preamble preserves that material when it is meaningful, and --remove-text can remove additional known metadata paragraphs. Published and modified timestamps are generated from the system clock at conversion time, while the project start and finish dates remain explicit options because they describe when the work happened rather than when the website file was created. The output path and asset directory are supplied separately, so each report can become its own project entry.
Embedded Youtube Videos
I realized that sometimes I want to demonstrate my work through a Youtube video. Thankfully, there’s astro-embed, which gives me a simple Astro component that I can utilizes inside of .mdx files. Noting that these files have to be .mdx, due to the utilization of a component within the Markdown.
With this, I can add any Youtube video to my Markdown, such as the following: