See how we built our intranet. Live + Q&A, June 30

Custom Sanity Action Not Updating Variables When Switching Between Documents

2 repliesLast updated: Nov 29, 2025

I have a custom action built. It is a Publish button that is attached to the corresponding Netlify build hook. We have several microsites within our Sanity studio, and each microsite has its own Publish button that kicks off a deploy. In my action code I get the microsite id that then sets the necessary variables for the site deploy. However, when I bounce around to different microsites to test the publish button, it isn't resetting the variables to jive with the new microsite id.
A condensed version of my code:


import React, {useState} from "react";
import {RocketIcon} from '@sanity/icons'
let siteName;
let hookId;
let baseHookUrl = "<https://api.netlify.com/build_hooks/>";
let postUrl;

export function PublishMicrositeAction(props) {
    let micrositeId = props.id;

    if (micrositeId == "abc") {
        siteName = "Publishing Root Site";
        hookId = "123abc";
        postUrl = `${baseHookUrl}${hookId}`;
    }
    if (micrositeId == "def") {
        siteName = "Publishing Essentials";
        hookId = "456def";
        postUrl = `${baseHookUrl}${hookId}`;
    }
    if (micrositeId == "ghi") {
        siteName = "Publishing Foundations";
        hookId = "789ghi";
        postUrl = `${baseHookUrl}${hookId}`;
    }
    
    console.log(micrositeId)

    const [isDialogOpen, setIsDialogOpen] = useState(false)

    if (props.type !== 'microsite') {
        return null
    }

    function formSubmit() {
        var request = new XMLHttpRequest();
        request.open('POST', postUrl, true);
        request.onload = function() { // request successful
        // we can use server response to our request now
          console.log(request.responseText);
        };
      
        request.onerror = function() {
          // request failed
        };
      
        request.send(new FormData(event.target)); // create FormData from form that triggered event
        event.preventDefault();

        setIsDialogOpen(false)
    }
      
    return {
      label: "Publish Microsite",
      icon: RocketIcon,
      onHandle: () =&gt; setIsDialogOpen(true),    
      dialog: isDialogOpen &amp;&amp; {
          type: 'modal',
          onClose:  () =&gt; setIsDialogOpen(false),
          content: &lt;div id="modal"  style={{paddingBottom: 30 + 'px'}}&gt;
          &lt;h3&gt;{siteName}&lt;/h3&gt;
          &lt;p&gt;Please enter a brief description of what was changed.&lt;/p&gt;
          &lt;form id="publishForm" onSubmit={formSubmit}&gt;
          &lt;label for="trigger_title"&gt;Message: &lt;/label&gt;
          &lt;input type="text" id="trigger_title" name="trigger_title"/&gt;
          &lt;button id="submitBtn" type="submit" style={{marginLeft: 10 + 'px'}}&gt;Publish&lt;/button&gt;
          &lt;/form&gt;
          &lt;/div&gt;
      }
    }
  }
Maybe I have stared at this too long to see my mistake or what I am missing. But I really need the micrositeId to be updated every time I switch to a new microsite. I can see when I console.log the props.id that it displays the correct id, but the variables do not reflect that.
AI Update

I can see the issue in your code! The problem is that you're using module-level variables (siteName, hookId, postUrl) that are declared outside your component. These variables are set once when the module loads and persist across component re-renders, which is why they're not updating when you switch between microsites.

Here's what's happening:

The fix: Move these variables inside your component function so they're recalculated on every render:

import React, {useState} from "react";
import {RocketIcon} from '@sanity/icons'

const baseHookUrl = "https://api.netlify.com/build_hooks/";

export function PublishMicrositeAction(props) {
    const [isDialogOpen, setIsDialogOpen] = useState(false)
    
    let micrositeId = props.id;
    let siteName;
    let hookId;
    let postUrl;

    // These now get set fresh on every render
    if (micrositeId == "abc") {
        siteName = "Publishing Root Site";
        hookId = "123abc";
    } else if (micrositeId == "def") {
        siteName = "Publishing Essentials";
        hookId = "456def";
    } else if (micrositeId == "ghi") {
        siteName = "Publishing Foundations";
        hookId = "789ghi";
    }
    
    postUrl = `${baseHookUrl}${hookId}`;
    
    console.log(micrositeId, hookId, postUrl) // Better debugging

    if (props.type !== 'microsite') {
        return null
    }

    function formSubmit(event) { // Don't forget to accept event parameter!
        event.preventDefault();
        
        var request = new XMLHttpRequest();
        request.open('POST', postUrl, true);
        request.onload = function() {
          console.log(request.responseText);
        };
      
        request.onerror = function() {
          console.error('Request failed');
        };
      
        request.send(new FormData(event.target));
        setIsDialogOpen(false)
    }
      
    return {
      label: "Publish Microsite",
      icon: RocketIcon,
      onHandle: () => setIsDialogOpen(true),    
      dialog: isDialogOpen && {
          type: 'modal',
          onClose:  () => setIsDialogOpen(false),
          content: <div id="modal" style={{paddingBottom: 30 + 'px'}}>
          <h3>{siteName}</h3>
          <p>Please enter a brief description of what was changed.</p>
          <form id="publishForm" onSubmit={formSubmit}>
          <label htmlFor="trigger_title">Message: </label>
          <input type="text" id="trigger_title" name="trigger_title"/>
          <button id="submitBtn" type="submit" style={{marginLeft: 10 + 'px'}}>Publish</button>
          </form>
          </div>
      }
    }
}

Key changes:

Even better approach - use a lookup object for cleaner code:

const MICROSITE_CONFIG = {
  abc: { name: "Publishing Root Site", hookId: "123abc" },
  def: { name: "Publishing Essentials", hookId: "456def" },
  ghi: { name: "Publishing Foundations", hookId: "789ghi" }
};

export function PublishMicrositeAction(props) {
    const [isDialogOpen, setIsDialogOpen] = useState(false)
    
    const config = MICROSITE_CONFIG[props.id];
    const postUrl = `${baseHookUrl}${config?.hookId}`;
    
    // ... rest of your code using config.name and postUrl
}

This makes it much easier to maintain and avoids the if/else chain entirely!

Show original thread
2 replies

Was this answer helpful?

Sanity – Build the way you think, not the way your CMS thinks

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.

Related contributions