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
 
 
              

 
    
Top comments (0)