I am creating a URL shortener as a personal project and I am attempting to make a copy button that when clicked copies the shortened URL with the attached hyperlink.
The URL shortening is handled with Formik and Yup, and I am using clipboard.js to copy the link. This is my first time using all of these APIs(?).
Currently, when the copy button is clicked, it copies the shortened URL but not the attached hyperlink. So when the shortened URL is pasted into the search bar it’s a dead end.
I’ve searched on how to do this but I could not find the relevant information. I would appreciate any help on how to solve this problem.
Below is what I currently have:
export default function Home() {
// =========== shortener = shortens the given url ===========
const shortener = new Shortener({
target: "https://short.ie/",
length: 8,
alphabet: "alphanumeric",
});
// =========== formik (= saves the form's data before and after submit) ===========
const formik = useFormik({
// what is saved while typing into the input box
initialValues: {
link: "",
},
validationSchema: Yup.object({
link: Yup.string()
.matches(
/((https?)://)?(www.)?[a-z0-9]+(.[a-z]{2,}){1,3}(#?/?[a-zA-Z0-9#]+)*/?(?[a-zA-Z0-9-_]+=[a-zA-Z0-9-%]+&?)?$/,
"Please enter a valid url"
)
.required("A URL is required"),
}),
onSubmit: (values) => {
setShortURL(shortener.shorten(values.link));
},
});
const clipboard = new ClipboardJS(".copy-btn");
const [shortURL, setShortURL] = useState("");
return (
<div id="container">
<div className="header-container">
<h1 id="header">URL Shortie</h1>
</div>
<div className="form-container">
<form onSubmit={formik.handleSubmit}>
{/* if the input has been "touched" (i.e. clicked on) and there is an error, display the error, else display 'your long url' */}
<label className="label">
{formik.touched.link && formik.errors.link
? formik.errors.link
: "Your Long URL"}
</label>
<input
className="input"
type="url"
name="link"
value={formik.values.link}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
placeholder="Enter your link here"
required
/>
<p className="label">Shortened URL HTML Div</p>
<div className="input copy">
{/* if shortURL is not empty then render shortend url,
else render onsubmit */}
{shortURL ? (
shortURL && (
<a id="result" href={shortURL.original} target="_blank">
{shortURL.target}
</a>
)
) : (
<a id="result" href="">
https://short.ie/
</a>
)}
</div>
<label htmlFor="" className="label">
Shortened URL HTML Input
</label>
{/* if shortURL is not empty render the target URL, else render base URL */}
<input
id="shortenedURL"
className="input"
type="text"
value={shortURL ? shortURL.target : "https://short.ie/"}
readOnly="readOnly"
/>
<div className="button-container">
<input className="submit-btn" type="submit" value="Shorten Url" />
<button
className="copy-btn"
type="button"
data-clipboard-action="copy"
data-clipboard-target="#result"
>
<span class="material-symbols-outlined">content_copy</span>
Copy
</button>
</div>
</form>
<h1 id="subheader">Previous URLs</h1>
<div className="previous-urls-container"></div>
</div>
</div>
);
}
2
Answers
Do you need to use Clipboard.js for copying text, or can you use a simple JavaScript code to copy text? If not, you can utilize the following JavaScript code to accomplish this task:
Input box below -> Shortened URL HTML Input text should get updated with the shorten URL first. I don’t see its getting updated with the shorten URL. Once it’s updated then you can just read the value of the input box on the click of copy button.
add a click handler which will copy the url from input box.