Random Name Generator - Free & Versatile Tool Random Name Generator
Generate perfect names for any purpose
{/* Buttons will be dynamically added here by JS */}
{/* Generated names will be listed here */}
Copying to clipboard is not supported or blocked in your browser.
Favorite Names
No favorite names saved yet.
`);
printWindow.document.close();
printWindow.focus();
printWindow.print();
showTooltip('printTooltip', 'Printing...');
}function saveAsPdf() {
if (currentGeneratedNames.length === 0) {
showTooltip('pdfTooltip', 'Nothing for PDF!');
return;
}
const element = document.createElement('div');
element.style.fontFamily = "Inter, Arial, sans-serif";
element.style.padding = "20px";
let htmlContent = '
Generated Names
';
currentGeneratedNames.forEach((name, index) => {
htmlContent += `- ${index + 1}. ${name}
`;
});
htmlContent += '
';
element.innerHTML = htmlContent;
const opt = {
margin: [0.5, 0.5, 0.5, 0.5],
filename: 'generated_names.pdf',
image: { type: 'jpeg', quality: 0.98 },
html2canvas: { scale: 2, logging: false, useCORS: true },
jsPDF: { unit: 'in', format: 'letter', orientation: 'portrait' }
};
showTooltip('pdfTooltip', 'Generating PDF...');
html2pdf().from(element).set(opt).save().then(() => {
showTooltip('pdfTooltip', 'PDF Saved!');
}).catch(err => {
showTooltip('pdfTooltip', 'PDF Error!');
console.error("PDF generation error:", err);
});
}
function exportAsTxt() {
if (currentGeneratedNames.length === 0) {
showTooltip('exportTxtTooltip', 'Nothing to export!');
return;
}
const textToExport = currentGeneratedNames.join("\r\n");
const blob = new Blob([textToExport], { type: "text/plain;charset=utf-8" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "generated_names.txt";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
showTooltip('exportTxtTooltip', 'Exported!');
}function renderFavorites() {
favoriteNamesListDiv.innerHTML = '';
if (favorites.length === 0) {
favoriteNamesListDiv.innerHTML = '
No favorite names saved yet.
';
clearFavoritesButton.disabled = true;
return;
}
clearFavoritesButton.disabled = false;
favorites.forEach(name => {
const itemDiv = document.createElement('div');
itemDiv.className = 'favorite-item-display';
const nameSpan = document.createElement('span');
nameSpan.className = "flex-grow break-all";
nameSpan.textContent = name;
itemDiv.appendChild(nameSpan);const removeBtn = document.createElement('button');
removeBtn.className = 'remove-fav-btn flex-shrink-0';
removeBtn.innerHTML = `
`;
removeBtn.title = "Remove from favorites";
removeBtn.onclick = () => {
favorites = favorites.filter(fav => fav !== name);
localStorage.setItem('rngUserFavoritesV2', JSON.stringify(favorites));
renderFavorites();
updateFavoriteIconsInResults();
};
itemDiv.appendChild(removeBtn);
favoriteNamesListDiv.appendChild(itemDiv);
});
}function toggleFavorite(name, heartIconSvg) {
const index = favorites.indexOf(name);
if (index > -1) {
favorites.splice(index, 1);
heartIconSvg.classList.remove('text-red-500');
heartIconSvg.classList.add('text-gray-400', 'hover:text-red-500');
heartIconSvg.parentElement.title = "Add to Favorites";
} else {
favorites.push(name);
heartIconSvg.classList.remove('text-gray-400', 'hover:text-red-500');
heartIconSvg.classList.add('text-red-500');
heartIconSvg.parentElement.title = "Remove from Favorites";
}
localStorage.setItem('rngUserFavoritesV2', JSON.stringify(favorites));
renderFavorites();
}
document.addEventListener('DOMContentLoaded', () => {
// currentYearSpan is removed, so no need to update it.
renderFavorites();
const startingLetterSelectElement = document.getElementById('starting-letter');
if (startingLetterSelectElement) {
const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (let letter of letters) {
const option = document.createElement('option');
option.value = letter;
option.textContent = letter;
startingLetterSelectElement.appendChild(option);
}
}
customOptionsDiv.classList.toggle('hidden', document.querySelector('input[name="nameSource"]:checked').value !== 'custom');document.querySelectorAll('.tooltiptext').forEach(tt => {
if (tt.textContent) {
tt.dataset.originalTitle = tt.textContent;
}
});
});