I think we have all been there. You have an idea for a new little side project and the stars finally align:
- You have a day free.
- Your IDE is up to date and you have a clear vision.
- You've setup your repository on GitHub.
- And if you're like me, you've just rolled a new React project using Vite for the first time.
Look. I know that create-react-app
was given the boot a loooong time ago but, and it was easy enough to get the ball rolling and setup typescript and everything else I wanted.
BUT. And here comes the but. I was busy working on my online resume. You know. That typical engineer-with-a-github-profile-thing where you use your Github page to host a small about you with some links.
Like most of you; I had the genius idea to throw my CV/Resume/Collection of my Professional Bones™ in a repo with my little cute React App and call it a day.
onClick: () => {
window.open("../../assets/resume.pdf", "_blank");
}
Locally, this works like a charm, however the moment my deploy pipeline wraps up its thing I realize with horror that I get a lovely 404 page.
Not to stress! This is pretty simple. Since I'm used a Webpack setup professionally (with a lot of customizations), I hadn't worked with Vite as a bundler before. In short, I just had to use Vite's way of handling assets and import my PDF document and use the import itself in my function:
import ResumeFile from "../../assets/resume.pdf";
onClick: () => {
window.open(ResumeFile , "_blank");
}
Now you're probably wondering why is this called the "Vite Chronicals" if all I had to do was change my import and all is good? Becuase I am not satisfied! That's why! When I click on my shiny new resume button, the actual resume is opened on this URL: https://svbygoibear.github.io/assets/resume.pdf
. What I want is it to open on https://svbygoibear.github.io/resume.pdf
. I know I can just move the PDF itself to my root/public folder but I want to keep it under assets but when I bundle and host it I want it at the root.
Which bings me back to the bundler... For this I added some extra configuration on build. This is my before:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
base: "/"
});
And this is my after:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
base: "/",
build: {
rollupOptions: {
input: {
main: "index.html"
},
output: {
assetFileNames: assetInfo => {
if (assetInfo?.name?.endsWith(".pdf")) {
return "[name][extname]";
}
return "assets/[name]-[hash][extname]";
}
}
}
}
});
The important part here is the output. Here I check if a file ends with PDF and I simply return it without the assets
root. Does this work though?
Now for my next challenge. I want to (very temporarily mind you) use a JSON file with a sample "payload" of my resume and read the file, parse it to typed instance and pass that around my relevant components instead of hardcoding it. But I just know will have more fun with Vite.
Until next time!
All I want to say with this article is that even after 10 years of working as a Software Engineer, you will still make silly mistakes. Make them! This is how you learn.
Versions Used
node: 18.14.0
vite: 6.3.3
react: 18.3.1