3D PRINTED • MADE TO ORDER

Fidgets that are
fun to click.

Cool, satisfying 3D-printed fidgets made in different colors and designs. Pick your favorites and build your collection.

Shop Fidgets →

Shop the collection

More designs can be added as the business grows.

⌨️

Keyboard Clicker

A compact, satisfying button fidget.

$5.00
Color: White
🌀

Infinity Fidget

Smooth movement in a pocket-sized design.

$6.00
Color: White
🐍

Flexi Fidget

A fun articulated print that moves in your hand.

$7.00
Color: White
🎮

Custom Keychain

Choose the base, top switch, bottom switch, filament colors, and size.

$6.00+

Base color

Switch 1 (top)

Switch 2 (bottom)

Size: Small — $6.00

Why Fidget Forge?

Small prints. Big fun.

🎨 Lots of colors

Choose from the filament colors available in the shop.

🖨️ 3D printed

Every item is printed to order.

⚙️ Custom options

Build your custom keychain with three color choices and different sizes.

Place an order

Add your items to the cart, then enter your information.

const colors = [ ["White","#f5f5f5"], ["Black","#050505"], ["Orange","#ff6a00"], ["Yellow","#ffd21c"], ["Red","#e62929"], ["Pink","#ff4fa0"], ["Green","#18c94a"], ["Blue","#1677d2"], ["Gray","#80838a"] ]; let cart = []; let custom = { base:"White", switch1:"White", switch2:"White", size:"Small", price:6 }; function makeSwatches(container,onPick){ colors.forEach(([name,hex],i)=>{ const button=document.createElement("button"); button.type="button"; button.className="swatch"+(i===0?" selected":""); button.style.background=hex; button.title=name; button.setAttribute("aria-label",name); if(name==="White"){ button.style.boxShadow=i===0?"0 0 0 2px #8b5cf6":""; } button.onclick=()=>{ onPick(name,button); }; container.appendChild(button); }); } document.querySelectorAll(".colors[data-group]").forEach(container=>{ const id=container.dataset.group; makeSwatches(container,(name,button)=>{ document.getElementById("color"+id).textContent=name; container.querySelectorAll(".swatch").forEach(item=>{ item.classList.remove("selected"); }); button.classList.add("selected"); }); }); function pickCustomSelect(key,name){ custom[key]=name; } function pickSize(size,price,button){ custom.size=size; custom.price=price; document.getElementById("customSize").textContent=size; document.getElementById("customPrice").textContent=price.toFixed(2); document.querySelectorAll(".size").forEach(item=>{ item.classList.remove("selected"); }); button.classList.add("selected"); } function addProduct(name,price,colorId){ const selectedColor=document.getElementById(colorId).textContent; cart.push({ name:name, price:price, color:selectedColor }); updateCart(); alert(name+" added to cart!"); } function addCustom(){ cart.push({ name:"Custom Keychain", price:custom.price, base:custom.base, switch1:custom.switch1, switch2:custom.switch2, size:custom.size, color:`Base: ${custom.base}, Top: ${custom.switch1}, Bottom: ${custom.switch2}` }); updateCart(); alert("Custom Keychain added to cart!"); } function updateCart(){ document.getElementById("count").textContent=cart.length; const box=document.getElementById("cartItems"); if(!cart.length){ box.innerHTML='

Your cart is empty.

'; }else{ box.innerHTML=cart.map((item,index)=>`
${escapeHtml(item.name)}
${escapeHtml(item.color||"")}
$${Number(item.price).toFixed(2)}
`).join(""); } const itemTotal=cart.reduce((sum,item)=>{ return sum+Number(item.price); },0); const shipping=cart.length?4.99:0; const grandTotal=itemTotal+shipping; document.getElementById("total").textContent=grandTotal.toFixed(2); } function removeItem(index){ cart.splice(index,1); updateCart(); } function openCart(){ updateCart(); document.getElementById("cartModal").classList.add("open"); } function closeCart(){ document.getElementById("cartModal").classList.remove("open"); } async function placeOrder(){ if(!cart.length){ alert("Your cart is empty."); return; } const name=document.getElementById("customerName").value.trim(); const email=document.getElementById("customerEmail").value.trim(); const address=document.getElementById("shippingAddress").value.trim(); const city=document.getElementById("shippingCity").value.trim(); const state=document.getElementById("shippingState").value.trim(); const zip=document.getElementById("shippingZip").value.trim(); const notes=document.getElementById("customerNotes").value.trim(); if(!name||!email){ alert("Please enter your name and email."); return; } if(!address||!city||!state||!zip){ alert("Please enter your complete shipping address."); return; } try{ const response=await fetch("/api/create-order",{ method:"POST", headers:{ "Content-Type":"application/json" }, body:JSON.stringify({ cart:cart, name:name, email:email, notes:notes, shippingAddress:{ address_line_1:address, admin_area_2:city, admin_area_1:state, postal_code:zip, country_code:"US" } }) }); const data=await response.json(); if(!response.ok){ throw new Error( data.error||"Could not create PayPal order." ); } const approvalLink=data.links?.find( link=>link.rel==="approve" ); if(!approvalLink){ throw new Error( "PayPal approval link was not returned." ); } window.location.href=approvalLink.href; }catch(error){ console.error(error); alert( error.message|| "Something went wrong." ); } } function escapeHtml(value){ return String(value??"").replace(/[&<>"']/g,char=>{ return { "&":"&", "<":"<", ">":">", '"':""", "'":"'" }[char]; }); } updateCart();