Basically, break it into pieces. Usually individual pages and estimate each based on prior experience. Add to it other things you may need to do like designing a schema, interfacing with other APIs, etc. This will probably give you your best case scenario. Then multiply times two because stuff always comes up that you didn't think about. This is what I use for "ballpark" estimates.
This is definately open to optimization.
I think it is important to understand "both sides". Clients usually like fixed-bid or per project pricing because it limits their risk. That way they won't be surprised by a huge bill.
As a freelance developer, I disklike fixed bids because it requires me to manage scope really carefully, otherwise my effective rate falls really quickly. So this really means that I need to increase my bid by some amount (I do 25%) do limit my exposure. So this isn't quite as good for the client as it might look on the surface.
A better way to do it is a lesser rate, such as hourly or weekly, and then break the work into iterations or phases, each resulting in something demonstrable so they can see what they are getting for their money. After they pay for the phase, they can walk with the source code written so far if they want. This limits risk on both sides. I've gotten paid for what I've done so far, and they have something tangible for what they've paid so far.
I start out with prototypes/proofs of concept to explore the most risky aspects of the application first and then feed what I find back into the estimate. This way, I can the client can know sooner than later about gotchas that can affect schedule or cost.