It was penalty heartbreak for Portugal.

France advanced to the UEFA Euro 2024 semifinals with a 0-0 (5-3 on penalties) victory in Hamburg.

Theo Hernandez scored the deciding penalty.

They will now play Spain in the final four.

Roberto Martinez went with an unchanged XI from the penalties victory over Slovakia, while Didier Deschamps made two changes for France from the 1-0 win over Belgium in the Round of 16. With Adrien Rabiot suspended, Eduardo Camavinga came into the midfield, while Randal Kolo Muani was preferred to Marcus Thuram up front.

After a fairly listless first half devoid of real chances, play opened up wide in the second 45 with both teams scratching their heads as to how they weren't lead on a number of occasions.

In the 50th, a give and go between Antoine Griezmann and Kylian Mbappé ended with the latter taking a shot from just outside the area that was directly at Diogo Costa. It was Mbappé's first real contribution offensively of the match.

Seconds later, Nuno Mendes went down in the France area and screamed for a penalty. Michael Oliver wasn't interested and replays showed that Mendes was lucky to get away without a caution for diving.

Hernandez created France's best chance of the early going in the half when his ball across the face of goal was just too far for Kolo Muani in the 52nd.

Mbappé found himself in a spot of bother in the 56th when he blocked a Bernardo Silva header from close range. Playing in a mask with a broken nose, the incoming Real Madrid man was in obvious pain and needed treatment. He stayed in the match.

In the 61st, Bruno Fernandes forced a diving stop of out Mike Maignan with a low drive from an angle. The ball fell for Joao Cancelo, who shot well over the bar instead of looking for an unmarked Cristiano Ronaldo near the penalty spot. Minutes later, it was even better from Maignan when he did well to stop Rafael Leao from close range before stopping a Ronaldo backheel and getting the ball out for a corner to end the danger.

It was Kolo Muani's turn to come close in the 66th. In alone on an angle, his effort was deflected by a fine tackle from Ruben Dias before being turned aside by Costa.

How on earth did Camavinga miss in the 70th? After good work from substitute Ousmane Dembélé, the ball fell to an unmarked Camavinga to the left of goal. With his weak foot, Camavinga scuffed his shot and missed the net entirely.

As the minutes ticked down, neither side wanted to take any real chances and settled for not making mistakes. After Thuram won a corner late into stoppage, Mbappé curled a shot from distance well over the bar before shrugging in frustration.

It was Ronaldo who had the best chance to score as extra time began. In the 93rd, Francisco Conceicao did well to keep a ball in play before finding the five-time Ballon d'Or winner in front of goal. From close range, Ronaldo rifled his shot miles over the bar.

Then in the 97th, Dembélé weaved his way through the Portuguese backline. Perhaps able to shoot himself, the Paris Saint-Germain man instead chose to drop off for Mbappé who rocketed a shot off of a defender.

Minutes later, Dayot Upamecano had a vital block to prevent Leao from picking the corner of Maignan's net and keep the match scoreless.

In the 108th minute, two subs almost combined for a fantastic opener. Conceicao delivered a delightful cross to the far post, but Joao Felix headed into the side netting when he really should have done better.

Dembélé finished off another good run in the 112th with a poor shot over the bar. Two minutes later, Bradley Barcola, on for Mbappé to start the second half of extra time, danced into the area and then pulled a shot over the bar from close range.

Mendes should have won it in the 120th, on a set-up by Bernardo Silva.

Poor finishing by both sides was the story of the match.