
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeI hear your frustration, and you're absolutely right – there's a gap in documentation for folks who want to use Sanity with just vanilla HTML, CSS, and JavaScript. You're not unskilled at all; the ecosystem has indeed focused heavily on framework-specific guides, and that makes it harder to see the simple path. Let me give you a straightforward explanation of how to set this up for a basic portfolio.
The Two-Part Setup
Sanity splits into two pieces:
Step 1: Set Up Studio (One-Time Thing)
You'll need Node.js installed just to create the Studio. Run:
npm create sanity@latestFollow the prompts - it'll ask you to create a project, choose a schema template (pick "blog" or "clean" for simplicity), and deploy. This gives you a Studio at yourproject.sanity.studio where you'll add your portfolio projects, blog posts, or whatever content you want.
Step 2: Fetch Content with Plain JavaScript
This is the part that should be simpler to find! Once you have content in your Studio, you can fetch it from any HTML page using Sanity's Query API. It's just a regular HTTP endpoint that returns JSON.
Here's a complete working example:
<!DOCTYPE html>
<html>
<head>
<title>My Portfolio</title>
<style>
.project { margin: 20px; padding: 20px; border: 1px solid #ccc; }
</style>
</head>
<body>
<h1>My Projects</h1>
<div id="projects"></div>
<script>
// Get these from your Sanity project settings
const projectId = 'YOUR_PROJECT_ID';
const dataset = 'production';
// GROQ query (Sanity's query language - similar to SQL)
const query = '*[_type == "project"]';
const encodedQuery = encodeURIComponent(query);
const url = `https://${projectId}.api.sanity.io/v2021-10-21/data/query/${dataset}?query=${encodedQuery}`;
fetch(url)
.then(response => response.json())
.then(data => {
const projects = data.result;
const container = document.getElementById('projects');
projects.forEach(project => {
const div = document.createElement('div');
div.className = 'project';
div.innerHTML = `
<h2>${project.title}</h2>
<p>${project.description || ''}</p>
`;
container.appendChild(div);
});
})
.catch(error => console.error('Error fetching projects:', error));
</script>
</body>
</html>Handling Images
Images in Sanity need special URL construction. When you get an image reference from Sanity, it looks like image-abc123-1200x800-jpg. You can build the URL manually:
function buildImageUrl(imageAsset, projectId, dataset) {
const ref = imageAsset.asset._ref;
// ref format: "image-{id}-{width}x{height}-{format}"
const parts = ref.split('-');
const id = parts[1];
const dimensions = parts[2];
const format = parts[3];
return `https://cdn.sanity.io/images/${projectId}/${dataset}/${id}-${dimensions}.${format}`;
}Or you can use the @sanity/image-url package if you want transformations (resizing, cropping, format conversion), though that requires installing via NPM. For a truly vanilla setup, the manual URL building above works fine.
Why This Feels Hidden
You're right that this should be more prominent. The reason framework guides dominate is:
But the core truth: Sanity is just an HTTP API that returns JSON. You can absolutely use it with vanilla JavaScript.
What You Need to Know
https://{projectId}.api.sanity.io/v2021-10-21/data/query/{dataset}?query={your-query}That's it! No React, no Next.js, no build tools needed for your actual website.
A Quick GROQ Primer
*[_type == "project"] - Get all documents of type "project"*[_type == "project"][0..5] - Get first 6 projects*[_type == "project"]{title, description, image} - Only return specific fieldsThe Studio setup is the only "complex" part, and even that's just running one command. Once that's done, you're just making fetch requests to get JSON data – exactly what you'd do with any other API.
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.
Content operations
Content backend


The only platform powering content operations
By Industry


Tecovas strengthens their customer connections
Build and Share

Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag store