✨Discover storytelling in the AI age with Pixar's Matthew Luhn at Sanity Connect, May 8th—register now

Minimal Example

A quick example on how a light weight front-end might be implemented.

Sanity comes with a editing environment called Sanity Studio and a data backend. Front-ends, however, you have to bring yourself. An ordinary website? A native mobile app? A PDF-factory? We make sure all your content is well structured so you get to decide how you want to use your data.

To get you started, here's an example. It's just a plain HTML-file with some equally plain JavaScript. Save it anywhere and you should be able to run it.

You can also try the same example on JSFiddle - just modify the project ID and dataset name. To complicate matters slightly you'll also need to add https://fiddle.jshell.net to your projects's CORS origins on sanity.io/manage.

<!doctype html>
  <meta charset="utf-8">
  <title>Sanity MovieDB frontend demo</title>
  <link rel="stylesheet" href="https://unpkg.com/purecss@0.6.2/build/pure-min.css">
  .movies {max-width: 800px; margin: 0 auto;}
  .poster {width: 80px; height: 120px;}
  .error {background: red; color: #fff; position: absolute; top: 0; bottom: 0; margin: 0; width: 100%;}

<table class="pure-table pure-table-bordered movies">

  <tbody id="movies">
      <td colspan="4">Loading...</td>

<script src="https://unpkg.com/@sanity/client@latest?main=umd"></script>
// If you drop the UMD bundle into a page, we attach to `window` as `SanityClient`.
// In node, or when using a bundler, you'd use `require('@sanity/client')`
var client = window.SanityClient({
  // Find your project ID and dataset in `sanity.json` in your studio project
  projectId: 'zp7mbokg',
  dataset: 'production',
  // Configure your client with an API version – https://www.sanity.io/docs/api-versioning
  apiVersion: '2021-08-26'

// Fetch 50 documents of type `movie`, and select only the fields we need
var query = `
  *[_type == "movie"]{
    "director": crewMembers[job == "Director"][0].person->name,
    "poster": poster.asset->url


// What follows isn't related to Sanity - just no-framework rendering logic
// Obviously, use whatever framework makes you happy!
var container = document.querySelector('#movies')

function renderMovies(movies) {
  while (container.firstChild) {

  movies.map(function(movie) {

function createPoster(poster) {
  var img = createElement('img')
  img.className = 'poster'
  img.src = poster + '?h=240'
  return img

function createMovieRow(movie) {
  return createElement('tr', [
    createElement('td', [createPoster(movie.posterUrl)]),
    createElement('td', [text(movie.title)]),
    createElement('td', [text(movie.releaseDate.utc.substr(0, 4))]),
    createElement('td', [text(movie.director || 'Unknown')])

function createElement(tag, childNodes) {
  var el = document.createElement(tag)
  var children = childNodes || []
  children.forEach(function (child) {
  return el

function renderError(err) {
  const errorBox = createElement('pre', [text(err.message)])
  errorBox.className = 'error'


function text(str) {
  return document.createTextNode(str)


Was this article helpful?