Connect your content
Assuming you've followed along with the previous steps of configuring the schema and editing content, you should be all set up for the next step of bringing your content to the world.
Since your content is just data available through an API, there’s practically no limit to where you can put it! It doesn’t even have to be the Web, as long as the system can send an HTTP request and do something with the returned JSON data. Of course, you can use Sanity with frameworks like Next.js, Nuxt.js, SvelteKit, Gatsby, Scully; you name it.
In this step, you will use HTML and JavaScript to query your Sanity project’s API and retrieve your pet document from the production dataset that it lives in.
You can choose a framework you're familiar with, try a new one, or proceed with the vanilla JavaScript and HTML example below.
👉 Start by opening this Codesandbox. Once you start editing the code and hit save, it will create a new fork personal to you.
It will already have the boilerplate code that we’re showing below. We'll add code to fetch data using a few lines of JavaScript inside the <script>
element.
In your code to fetch data, you need two pieces of information to connect to your API:
- A Project ID
- A Dataset name
👉 There are multiple places where you can find these, but today you should head over to sanity.io/manage. Here you’ll find your project(s) and the project settings. If you click into the project (you probably only have the one you just made), then the Project ID
will be under the project name. Use the project ID to replace the YOUR_PROJECT_ID
placeholder in the code.
👉 Then, navigate to the tab called Datasets
. If you follow this tutorial, you’ll find only one called production
. Add this as the value for the DATASET
variable.
<!DOCTYPE html>
<html lang="en">
<head>
<title>My pets</title>
<meta charset="UTF-8" />
<link rel="stylesheet" href="src/styles.css" />
</head>
<body>
<header>
<h1>Sanity + Vanilla JavaScript</h1>
</header>
<main>
<h2>Pets</h2>
<ul>
<li>Loading pets…</li>
</ul>
<div>
<pre>
¯\_(ツ)_/¯
Your data will show up here when you've configured everything correctly
</pre>
</div>
</main>
<script>
let PROJECT_ID = "YOUR_PROJECT_ID";
let DATASET = "production";
</script>
</body>
</html>
The plan is to fetch your content using JavaScript that runs in the browser. Browsers come with security that prevents code injection that steals information from your cookies and passes them to third parties. This is called CORS. To allow your CodeSandbox site to get content from your project, you need to add its URL to your project’s CORS origins settings.
👉 First, grab the URL from the preview pane in your Codesandbox, it should look something like this https://RANDOM_LETTERS.csb.app/
.
👉 Then head over to the API tab in your project settings at sanity.io/manage. A little bit down the page you'll find the section named "CORS Origins". Click the button labeled "Add CORS Origin", paste the URL from Codesandbox into the URL field, and hit save (you don’t need to “Allow credentials”). That’s it!
You need to send a query to an API endpoint to fetch content. In other words, you need to put together an URL. Normally, you’d use a client library, but in this minimalist example, you’ll construct this URL yourself using the project ID, the dataset name, a query, and Sanity’s URL endpoint for content queries.
👉 Add two new variables to your CodeSandbox project, QUERY
and URL
:
let QUERY = encodeURIComponent('*[_type == "pet"]');
// Compose the URL for your project's endpoint and add the query
let URL = `https://${PROJECT_ID}.api.sanity.io/v2021-10-21/data/query/${DATASET}?query=${QUERY}`;
This is what your code should look like now:
<!DOCTYPE html>
<html lang="en">
<head>
<title>My pets</title>
<meta charset="UTF-8" />
<link rel="stylesheet" href="src/styles.css" />
</head>
<body>
<header>
<h1>Sanity + Vanilla JavaScript</h1>
</header>
<main>
<h2>Pets</h2>
<ul>
<li>Loading pets…</li>
</ul>
<div>
<pre>
¯\_(ツ)_/¯
Your data will show up here when you've configured everything correctly
</pre>
</div>
</main>
<script>
let PROJECT_ID = "YOUR_PROJECT_ID";
let DATASET = "production";
let QUERY = encodeURIComponent('*[_type == "pet"]');
// Compose the URL for your project's endpoint and add the query
let URL = `https://${PROJECT_ID}.api.sanity.io/v2021-10-21/data/query/${DATASET}?query=${QUERY}`;
</script>
</body>
</html>
The QUERY
variable consists of two parts. The encodeURIComponents
function ensures that the query string can be sent inside an URL. The *[_type == "pet"]
string is a simple GROQ query. GROQ is the primary query language that Sanity uses.
The URL
variable takes the variables you have defined and uses string concatenating to put them together.
Almost done! The last part of this is to add a fetch
function that takes the URL
and then
extracts the returned JSON out of the response and then
passes it to a callback function where you can output the data to the DOM, that is, your pre
tag. If something wrong happens, you’ll catch
that and console.log
the error.
<!DOCTYPE html>
<html lang="en">
<head>
<title>My pets</title>
<meta charset="UTF-8" />
<link rel="stylesheet" href="src/styles.css" />
</head>
<body>
<header>
<h1>Sanity + Vanilla JavaScript</h1>
</header>
<main>
<h2>Pets</h2>
<ul>
<li>Loading pets…</li>
</ul>
<div>
<pre>
¯\_(ツ)_/¯
Your data will show up here when you've configured everything correctly
</pre>
</div>
</main>
<script>
// Select the DOM-element, so that you can replace it with content
let PROJECT_ID = "YOUR_PROJECT_ID";
let DATASET = "production";
let QUERY = encodeURIComponent('*[_type == "pet"]');
// Compose the URL for your project's endpoint and add the query
let URL = `https://${PROJECT_ID}.api.sanity.io/v2021-10-21/data/query/${DATASET}?query=${QUERY}`;
// fetch the content
fetch(URL)
.then((res) => res.json())
.then(({ result }) => {
// get the list element, and the first item
let list = document.querySelector("ul");
let firstListItem = document.querySelector("ul li");
if (result.length > 0) {
// remove the placeholder content
list.removeChild(firstListItem);
result.forEach((pet) => {
// create a list element for each pet
let listItem = document.createElement("li");
// add the pet name as the text content
listItem.textContent = pet?.name;
// add the item to the list
list.appendChild(listItem);
});
let pre = document.querySelector("pre");
// add the raw data to the preformatted element
pre.textContent = JSON.stringify(result, null, 2);
}
})
.catch((err) => console.error(err));
</script>
</body>
</html>
That’s it! Now you should be able to refresh the page in your preview and see the JSON of your pet document. If you publish a change in the studio, that should be reflected here too when you reload.