I'm glad you got it working. Yes, \require does do special things. In particular, it has to load the require extension, and that is an asynchronous action, which is where the "Promise" part of "tex2mmlPromise()" comes in. Because this function returns a promise, you need to be sure to wait for that promise before allowing MathJax to typeset the page (otherwise the definitions won't be in place when the page is rendered). It looks like your page (linked in your original page below) has the order reversed: you wait for the initial typesetting before defining the macros. That is, you have
pageReady() {
return MathJax.startup.defaultPageReady().then(function() {
MathJax.tex2mmlPromise(String.raw`
...
`)
});
}
The defaultPageReady() function does the initial typesetting, and since you wait for that before the tex2mmlPromise(), that is the wrong order. It should be
return MathJax.tex2mmlPromise(
String.raw`
...
`
).then(MathJax.startup.defaultPageReady)
.then(rsMathReady);
so that the definitions are in place before the startup typesetting is performed.
Note also that your code doesn't wait for the tex2mmlPromise to resolve (the function that calls it would have had to return the promise in order for the .then() to have waited for it), so the .then() will resolve before tex2mmlPromise() executes. Because the tex2mmlPromise commands include \require{cancel}, that will guarantee that other code will run before the definitions are processed.
I think if you handle the promises correctly, you should be able to use \require within your definitions.
Davide