Deploy Your First Static Site
In this lesson, the goal is not to launch a business site. The goal is to understand what Vercel receives, what it serves, and what evidence proves the deployment worked. You will learn what a small static project looks like, when a build command is unnecessary, how the output directory matters, and how to inspect the generated URL after deployment.
Use a personal, non-commercial Vercel account for course practice if the current plan terms allow it. Do not use this exercise to host a client, employer, paid, ad-supported, or production business project. The previous lesson explained why commercial use needs plan review and proper ownership.
What Static Means
A static site is made of files that can be served as-is. The server does not need to run application code to create the response for each request. If the browser asks for /index.html, the platform returns an HTML file. If the HTML references /styles.css, the browser asks for that CSS file. If the page references /app.js, the browser downloads and executes that JavaScript in the browser.
A static site can still be interactive. JavaScript can open menus, validate form fields, fetch public APIs, render client-side components, or store state in the browser. Static does not mean boring. It means the deployment output is already built and ready to serve.
A static site is not the right place for secrets. Anything delivered to the browser is public to the user. If an API key appears in app.js, a visitor can read it. If a private document is placed beside index.html, it may be served. If a database dump is committed to the repository, deployment settings are not the real problem; the repository now contains private data.
For this first deployment, keep the project intentionally plain:
vercel-static-first-site/
index.html
styles.css
app.js
There is no package.json, no build step, and no framework. That is useful because every deployed file is visible in the project folder.
Create The Site Files
Create a new folder outside any private production project. Name it something obvious, such as vercel-static-first-site. Inside it, create index.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>First Vercel Static Site</title>
<link rel="stylesheet" href="/styles.css">
</head>
<body>
<main class="page">
<h1>First Vercel Static Site</h1>
<p>This page was deployed from static files.</p>
<button id="check-button" type="button">Check JavaScript</button>
<p id="status" aria-live="polite">JavaScript has not run yet.</p>
</main>
<script src="/app.js"></script>
</body>
</html>
Create styles.css:
body {
margin: 0;
font-family: system-ui, sans-serif;
color: #1f2933;
background: #f3f7f0;
}
.page {
max-width: 42rem;
margin: 4rem auto;
padding: 2rem;
}
button {
padding: 0.7rem 1rem;
border: 1px solid #284b63;
background: #ffffff;
color: #102a43;
}
Create app.js:
const button = document.querySelector('#check-button');
const status = document.querySelector('#status');
button.addEventListener('click', () => {
status.textContent = 'JavaScript is running from the deployed static file.';
});
Open index.html locally in a browser. You should see the heading, paragraph, button, and status text. Click the button and confirm the text changes. This local check is not a Vercel deployment yet. It only proves that the three files work together before you upload or connect them.
Understand Build Output
Build output is the set of files Vercel serves after the project is built. For this plain static site, the source files are also the deployable output. There is no compile step. The output is simply:
index.html
styles.css
app.js
Many later projects are different. A Vite project may have source files in src/ and generate deployable files in dist/. A Next.js project has its own build process and output. A documentation generator might turn Markdown files into HTML. In those cases, Vercel must know the build command and the output directory.
For a plain static project with no build command, the important setting is that Vercel serves the correct directory. Vercel's build settings documentation explains that for projects without a build, the framework preset can be Other, the build command can be left empty, and the content can be served directly. If a public directory exists, Vercel may use that as the output directory for the Other preset; otherwise, it can serve the project root. Because this lesson uses the root directory and no public/ folder, the files are easy to reason about.
The mistake to avoid is deploying the wrong directory. If index.html is in a subfolder but Vercel is pointed at the repository root, the deployment may show a 404 or a directory that does not contain your site. If a framework outputs to dist/ but the project is configured to serve public/, the build may pass while the deployed page is wrong.
Deploy From The Dashboard
The beginner-friendly path is the Vercel Dashboard. You can deploy by importing a Git repository, but this lesson can also be practiced with a simple project upload or CLI workflow depending on what the current dashboard offers. The next lesson focuses on GitHub and automatic deployments, so keep this first deployment narrow: one static site, one generated URL, one verification pass.
If you use a Git repository now, keep it personal and non-commercial. Commit only the three site files and any harmless README. Do not commit .env files, API keys, screenshots containing private data, certificates, or client assets you do not have permission to publish.
In the Vercel Dashboard, create a new project and select the repository or upload path for the static site. When Vercel asks for framework settings, use the option that matches a plain static site. The general shape is:
Framework Preset: Other
Build Command: empty / skipped
Output Directory: root directory, unless your files are in public/
Install Command: not needed for this plain static project
The exact dashboard wording can change, so treat those lines as the intent rather than as a screen-by-screen script. The key is that this project has no package installation, no build command, and no separate output folder. You want Vercel to serve the static files directly.
After deployment, Vercel should provide a generated deployment URL. Open it in a browser. You should see the same page you tested locally. Click the button and confirm the JavaScript status text changes.
Deploy From The CLI
The Vercel CLI is another deployment method. It is useful when you want to deploy from the terminal, test project linking, or understand what Vercel creates locally. You do not need it for every beginner deployment, but it is worth knowing the shape of the workflow.
A typical CLI deployment begins from the project root:
vercel
The CLI may ask you to log in, choose a scope, link or create a project, and confirm settings. For a production deployment, Vercel's deployment documentation shows vercel --prod as the command that creates a Production Deployment from the local project. Do not run production deployments casually for shared, client, or business work. For course practice, a generated preview deployment is usually enough.
The CLI can create a .vercel/ directory that stores project-linking metadata. That directory identifies the linked Vercel project and organization. It should normally not be edited by hand. Before committing, check whether your repository's ignore rules should exclude local Vercel metadata according to your project policy.
The CLI is not a substitute for understanding the output. Whether the deployment starts from the dashboard, Git, or CLI, you still need to know which files were deployed and which URL proves they are live.
Verify The Deployment
A deployment is not done just because the build says it completed. Open the generated URL and verify specific behavior.
For this lesson, check:
- the page loads without a 404;
- the title and heading match your local file;
- the CSS is applied;
- the JavaScript button changes the status text;
- browser DevTools show no missing
styles.cssorapp.jsrequests; - the generated URL is a Vercel deployment URL, not your local
file://path; - the deployed content contains no private notes, keys, or test data.
If the page is blank, inspect the browser console and network panel. A missing CSS file is usually a path issue. A missing JavaScript file may be a wrong filename, wrong path, or case mismatch. Linux-based deployment environments are case-sensitive, so App.js and app.js are different names.
If Vercel shows a 404, check where index.html is relative to the configured root and output directory. If Vercel ran an unexpected build command, check the framework preset and build command settings.
Understand The Generated URL
Each Vercel deployment gets a generated URL. That URL is useful evidence. It lets you confirm the deployment independently of your local machine, share the result for review, and compare one deployment with another.
Do not confuse the generated URL with a production custom domain. A generated URL proves the deployment exists. A production domain is a later step that points a real domain, such as example.com, at the intended Production Deployment. This lesson stops at the generated URL because the next steps need more vocabulary: Git integration, Preview Deployments, Production Deployments, and domains.
For a course exercise, write down:
Project: vercel-static-first-site
Deployment method: dashboard, Git, or CLI
Build command: none
Output directory: root directory
Generated URL: https://example-project-abc123.vercel.app
Verified: HTML, CSS, JavaScript, no private files
Use your actual generated URL. Do not paste credentials or private dashboard links into course notes.
Common First-Deployment Mistakes
The first mistake is deploying a folder that does not contain index.html. A browser request to / needs an entry page. If the file is nested one level deeper, Vercel may not serve what you expect.
The second mistake is assuming local paths behave like web paths. In HTML, href="/styles.css" asks for styles.css from the site root. href="styles.css" asks relative to the current page. Both can work in simple cases, but inconsistent paths become painful when files move.
The third mistake is leaving a build command from a different project. If Vercel tries to run npm run build but your static site has no package.json, the deployment can fail. For a plain static project, the build step should be skipped.
The fourth mistake is publishing private files. A static deployment should contain only files meant for public download. Do not include design briefs, client notes, database exports, API keys, .env files, certificates, raw private assets, or personal documents. Later lessons cover .vercelignore, but the safe habit starts now: deploy from a clean project folder.
The fifth mistake is treating the generated URL as a permanent production plan. Generated URLs are excellent for learning and previewing, but a real production launch needs domain, plan, ownership, security, logging, and rollback decisions.
Review Questions
- What makes this lesson's project a static site?
- Why does this project not need a build command?
- What is the output directory for the plain static example?
- How can you prove that the deployed page is not just your local file?
- What should you check if CSS or JavaScript works locally but not after deployment?
- Which private files should never be included in a static deployment?