How to use the Mintplex embed with custom buttons

Sometimes the default styling for our button is insufficient for the theme or layout of your minting site.

All implementations will be slightly different depending on the framework or codebase of your website. Mintplex cannot guarantee support for your specific codebase. While we know this process does work with all JS and static HTML frameworks, it is up to the developer to ensure implementation is done correctly.

When you should be doing this...

  • You have a website with a specific theme or layout in which our default button is inadequate.

  • You use a JS-rendered (React, Vue, etc) site where the implementation of an HTML snippet is not easy to include.

  • You want complete control of the style and layout of the button, but do not have to worry about all the complex contract logic associated with minting.

Implementation

In general you would take your HTML snippet from your Mintplex project page and then add a new data-attribute to the HTML like so...

<!-- Minting button provided by Mintplex.xyz -->
    <div id='rampp-minting-container-1461b754-eeb4-47f4-8cef-02262623c9ea' class='rampp-minting-container'>
      <button 
        id='rampp-minting-button-1461b754-eeb4-47f4-8cef-02262623c9ea' 
        class='rampp-minting-button'
        ...
        data-custom-mode="true"  <-- Add this!!! -->
      ></button>
    </div>
    <!-- 
      Don't forget all the default scripts that are imported in the normal Embed.
      Especially don't forget the Mintplex/embed script!
    -->
    <script type='text/javascript' src="https://mintplex.xyz/embeds/v2.1/embed.js"
      data-uuid='1461b754-eeb4-47f4-8cef-02262623c9ea'></script>
<!-- End Mintplex.xyz minting button-->

Importing the above anywhere in the component/page will have the mintplex button code load but with data-custom-mode=true the button will not render but all logic is available.

To invoke a simple call window.executeMint(qty); to start the minting process.

HTML

Working Example: https://replit.com/@timothycarambat/RamppCustomInvoke#index.html

Here we have a regular HTML button as so

<button onclick="window.handleMint();">
    This is a random custom button elsewhere on the page
</button>

With a supporting minting action that is written as so:

 <script>
    window.handleMint = async () => {
      const quantity = 2// Get this from somewhere - must be a number...
      const result = await window.executeMint(quantity); // available from Mintplex/embed.js import
      console.log({result}) // will be null if failed, otherwise TXN hash.
    }
  </script>

React.js

With React or other JS-rendering frameworks, you will need to be more proficient with your framework of choice as we do not provide a default library or NPM package to support this flow - that being said implementation can be trivial.

Working Example: https://replit.com/@timothycarambat/ReactJS-with-Custom-Mode-Mintplex-Embed

Here we again have a custom button component

import { useState } from 'react'

function CustomMintButton() {
  useMintplexEmbed('1461b754-eeb4-47f4-8cef-02262623c9ea'); // see next code block
  const [quantity, setQuantity] = useState(1)

  const handleClick = async () => {
    console.log(`Minting ${quantity}`)
    const result = await window?.executeMint(quantity);
    console.log({ result })
    return;
  }

  return (
    <div style={{ display: 'flex', gap: '10px', width: '100vw' }}>
      <button
        onClick={handleClick}
        style={styles}>
        My custom Mint button
      </button>
      <input
        type='number'
        defaultValue={quantity}
        onChange={({ target }) => setQuantity(Number(target.value))}
      />
    </div>
  )
}

We also abstract out the creation and embedding of the HTML component into a React hook. There are other ways to do this of course, but this is just an example of how to do it.

import { useEffect } from 'react'

// uuid is just a random string, can be anything. Doesnt have to be what was
// provided by the Mintplex embed. UUIDs on the scripts allows multiple Mintplex
// embeds to be present on the same page, thats all.
function useMintplexEmbed(uuid) {
  useEffect(() => {
    if (!window?.document) return;
    if (!!window.document.getElementById(`rampp-minting-container-${uuid}`)) return;

    const container = window.document.createElement('div')
    container.setAttribute('id', `rampp-minting-container-${uuid}`)

    const btn = window.document.createElement('button')
    btn.setAttribute('id', `rampp-minting-button-${uuid}`)
    btn.setAttribute('style', 'display:none')
    btn.setAttribute('data-merkle-proof-uri', 'https://us-central1-nft-rampp.cloudfunctions.net/allowlist/b1myAelVTJ8uOQTRzeNB/merkle/verify')
    btn.setAttribute('data-abi-link', 'https://firebasestorage.googleapis.com/v0/b/nft-rampp.appspot.com/o/solidity_outputs%2Fb1myAelVTJ8uOQTRzeNB%2FMyMintplexProjectContract_data-bbe2cd2f-2e6e-4375-aeeb-f91229ef6d67.json?alt=media')
    btn.setAttribute('data-redirect', null)
    btn.setAttribute('data-contract-address', '0x95c62366310214B393176cD67DEc1AA466F0C9A8')
    btn.setAttribute('data-network', 'goerliArbitrum')
    btn.setAttribute('data-custom-mode', true)

    window.document.body.appendChild(container)
    container.appendChild(btn)

    // Dont forget the scripts!
    // again, a million ways to do this - just ensure scripts are present.
    const srcs = {
      'https://cdnjs.cloudflare.com/ajax/libs/web3/1.7.0-rc.0/web3.min.js': null,
      'https://unpkg.com/web3modal@1.9.8/dist/index.js': null,
      'https://unpkg.com/evm-chains@0.2.0/dist/umd/index.min.js': null,
      'https://unpkg.com/@walletconnect/web3-provider@1.7.8/dist/umd/index.min.js': null,
      'https://mintplex.xyz/embeds/v2.1/embed.js': uuid,
    }

    Object.entries(srcs).forEach(([key, value]) => {
      const script = window.document.createElement('script')
      script.setAttribute('src', key)
      if (!!value) script.setAttribute('data-uuid', value)
      container.appendChild(script)
    })
  })
}

That's all!

Of course, you should always test your button on the testnet contract to ensure it works, and then when on mainnet copy the new data-attributes to the existing integration in your code, and all should work! If clicking the button opens MetaMask - you are done!

Last updated