# How to use the Mintplex embed with custom buttons

{% hint style="warning" %}
**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.
{% endhint %}

### 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.
* &#x20;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...

```html
<!-- 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

```html
<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:

```html
 <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](https://replit.com/@timothycarambat/ReactJS-with-Custom-Mode-Mintplex-Embed#src/App.jsx)<br>

Here we again have a custom button component

```jsx
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.

```jsx
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!
