Samuel Umtiti’s header from a corner proved enough, as France ended Belgium’s 24-game unbeaten run and reached the World Cup Final.
It’s their first Final since losing the 2006 showdown to Italy on penalties, but in Moscow they’ll face either England or Croatia this weekend.
With Thomas Meunier suspended, Belgium brought in Nacer Chadli and again benched Dries Mertens, while France had Juventus midfielder Blaise Matuidi back from his ban to replace Corentin Tolisso.
Thibaut Courtois smothered at the feet of Kylian Mbappé and Eden Hazard flashed an angled drive across the face of goal, but on 19 minutes Raphael Varane got the top of his head to a Hazard strike, turning it inches over the bar.
Belgium continued to push, Hugo Lloris palming a Toby Alderweireld curler round the post, but Courtois stuck out a long leg to deny Pavard at the near post.
It was Les Bleus who took the lead at the dawn of the second half, as Samuel Umtiti glanced a header from an Antoine Griezmann corner at the near post, getting in front of Marouane Fellaini.
France almost created an astoundingly cheeky goal, but Mbappé’s back-heel flick to set up Giroud was blocked by desperate defending in the six-yard box.
Napoli star Mertens was introduced and immediately his cross was nodded just wide by Fellaini, while Axel Witsel stung the gloves of the French goalkeeper.
Belgium ultimately didn't have enough on a poor night for Romelu Lukaku and Courtois prevented a second goal in stoppages from Corentin Tolisso.
France 1-0 Belgium
Umtiti 51 (F)
France: Lloris; Pavard, Varane, Umtiti, Hernandez; Pogba, Kante; Mbappé, Griezmann, Matuidi (Tolisso 86); Giroud (N’Zonzi 85)
Belgium: Courtois; Alderweireld, Kompany, Vertonghen; Chadli (Batshuayi 91), Dembélé (Mertens 60), Witsel, Fellaini (Carrasco 80), De Bruyne; E Hazard, Lukaku
Ref: Cunha (URU)