Note that https://hello is a valid URL according to the new URL() constructor. Should maybe check if value contains at least one dot.
import z from "zod";
export const zodUrlOrLocalhost = z.string().refine(
(value) => {
if (value === "localhost") {
return true;
}
let valueWithProtocol = value;
if (!value.startsWith("http://") && !value.startsWith("https://")) {
// Prepend https:// for .url to work since zod hates URLs without protocol
valueWithProtocol = `https://${value}`;
}
const urlSchema = z.string().url();
const result = urlSchema.safeParse(valueWithProtocol);
return result.success;
},
{
message: "Host must be a valid URL",
},
);