Learn how to add a button to any contact field link.
Overview
This simple JavaScript (ECMAScript) will add this button to ANY custom contact field containing a link.
Here are some examples:
The button color, text, and effects can be customized.
By default, the link will open in a NEW tab.
How to Implement
Implementing this is extremely easy!
Note that you need to have agency access to add custom JS, but all you need to do is follow the video guide above, or just paste the code below into:
Agency View → Settings → Company → Whitelabel → Custom JS
If you want to customize the color/text/behavior of the button, scroll down to the section on Customizing.
<script>
function isValidUrl(string) {
try {
const url = new URL(string)
return url.protocol === "https:" || url.protocol === "http:"
} catch (_) {
return false
}
}
function transformUrlField(urlInput) {
console.log("Attempting to transform URL field:", urlInput)
if (!urlInput || !urlInput.value) {
console.log("URL input invalid or empty, returning")
return
}
// Check if we've already transformed this field
const existingWrapper = urlInput.closest(".website-field-wrapper")
if (existingWrapper) {
console.log("Field already transformed, skipping")
return
}
// Find the input container div
const inputContainer = urlInput.closest(".hl-text-input-container")
if (!inputContainer) {
console.log("Input container not found, returning")
return
}
// Only transform if it's a valid HTTPS URL
if (!isValidUrl(urlInput.value)) {
console.log("Not a valid HTTPS URL, skipping")
return
}
// Create a wrapper div for flex layout
const wrapper = document.createElement("div")
wrapper.className = "flex gap-2 items-center website-field-wrapper"
// Move the input into the wrapper
urlInput.parentNode.insertBefore(wrapper, urlInput)
wrapper.appendChild(urlInput)
// Adjust input styles to accommodate button
urlInput.style.flex = "1"
// Create the button
const button = document.createElement("a")
button.href = urlInput.value
button.target = "_blank"
button.className =
"flex-shrink-0 px-3 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 hover:text-white text-sm"
button.textContent = "Visit →"
button.style.minWidth = "70px"
button.style.textAlign = "center"
// Add button to wrapper
wrapper.appendChild(button)
// Update button href when input changes
urlInput.addEventListener("input", (e) => {
if (isValidUrl(e.target.value)) {
button.href = e.target.value
button.style.display = "block"
} else {
button.style.display = "none"
}
})
console.log("Added visit button next to input")
}
function transformAllUrlFields() {
console.log("Transforming all URL fields...")
// Find all input fields
const allInputs = document.querySelectorAll('input[type="text"]')
allInputs.forEach((input) => {
if (input.value && isValidUrl(input.value)) {
transformUrlField(input)
}
})
}
function setupUrlFields() {
console.log("Setting up URL fields...")
// Check if we're on a contact detail page
if (!window.location.pathname.includes("/contacts/detail/")) {
console.log("Not on a contact detail page, setup not started")
return
}
// Wait for elements to exist before transforming
const waitForElements = setInterval(() => {
const anyInput = document.querySelector('input[type="text"]')
if (anyInput) {
console.log("Inputs found")
clearInterval(waitForElements)
transformAllUrlFields()
// Set up observer after initial transform
const observer = new MutationObserver((mutations) => {
const inputs = document.querySelectorAll('input[type="text"]')
inputs.forEach((input) => {
const existingWrapper = input.closest(
".website-field-wrapper"
)
if (
input.value &&
isValidUrl(input.value) &&
!existingWrapper
) {
console.log(
"New URL input found without wrapper, transforming..."
)
transformUrlField(input)
}
})
})
// Observe the entire document for changes
observer.observe(document.body, {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ["value"]
})
} else {
console.log("Waiting for inputs to appear...")
}
}, 1000) // Check every second
}
// Start the setup
console.log("Script started")
setupUrlFields()
</script>
Customizing
You may want to customize the color or text of the button. This is extremely easy to do.
Changing Color
To change the color, you have 2 options:
- Use a Tailwind default color class. Your options are here: https://tailwindcss.com/docs/colors
- Your chosen color will be something in the format of
blue-500
(default) - Change the given script like so:
- Use a custom hex or HSL color code. I prefer hex
- Your hex code will look something like #123ABC (numbers 1-9 and letters A-F represent a 16-digit counting system, 1 digit for each color.)
button.className = "flex-shrink-0 px-3 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 hover:text-white text-sm"
// Change 'bg-blue-500' to your tailwind class, ex: bg-red-400, and the 'hover:bg-blue-600' to ex: hover:bg-red-500 (this is the color when the button is hovered over)
button.className = "flex-shrink-0 px-3 py-2 text-white rounded hover:text-white text-sm"
// ^ Remove bg-blue-500 and hover:bg-blue-600 from button.className
button.style.backgroundColor = "#3B82F6"
// ^ Add this button.style.backgroundColor attribute with your default hex color
button.addEventListener("mouseenter", () => {
button.style.backgroundColor = "#2563EB"
})
// ^ Add this button.addEventListener("mouseenter") attribute with your hovered state color
button.addEventListener("mouseleave", () => {
button.style.backgroundColor = "#3B82F6"
})
// ^ Add this eventListener which will reset the color back to default when the mouse stops hovering the button
button.style.transition = "background-color 0.2s"
// ^ This line will give us a nice gradual transition of colors when you hover over the button
Changing Text
To change the displayed text, just edit this attribute:
button.textContent = "Visit →"
// Change the value in quotes to anything else, ex: "Go", "Go ->", "Open", etc.
Changing Behavior & Style
If you’re familiar with JS or Tailwind, then you already know that you can change other things in this script to suit your preferences.
Or just ask your smartest LLM for help with customization.
Features
- Uses Tailwind classes to add effects and colors to the button
- Always shown even when you hide/show the field
Ready to Install?
When you’re ready to install any app, click the link below to be taken through our installation wizard which can help you get it installed!
Frequent Questions
Do you offer custom development work?
Should I install your app at the agency level or location level?
What’s your support like?
How do I install your app?
Do you offer a free trial?
Can I request a feature or product?
Are there any usage limits on your apps?
Can I use your app on multiple accounts?
How do I uninstall the app?
Need to Get in Touch?
If you have any questions, concerns, or ideas, I’d love to hear them!
Visit the page below to book a call or get in touch right away.