{"id":37,"date":"2024-06-03T09:00:01","date_gmt":"2024-06-03T09:00:01","guid":{"rendered":"https:\/\/dover-dunkirk.com\/nl\/timetable\/"},"modified":"2026-09-28T20:05:39","modified_gmt":"2026-09-28T20:05:39","slug":"vaarschema","status":"publish","type":"page","link":"https:\/\/dover-dunkirk.com\/nl\/vaarschema\/","title":{"rendered":"Vaartijden Duinkerken naar Dover"},"content":{"rendered":"\n<div class=\"dd-hero dd-hero--page\"><img fetchpriority=\"high\" src=\"https:\/\/dover-dunkirk.com\/nl\/wp-content\/uploads\/sites\/3\/2026\/09\/delft-seaways-bow-loading-ramp.webp\" alt=\"De Delft Seaways aan de kade in Loon-Plage met de laadklep omlaag\" width=\"1400\" height=\"1050\" fetchpriority=\"high\" decoding=\"async\"><\/div><div class=\"dd-wrap\">\n\t<div class=\"dd-page-head dd-page-head--card\">\n\t\t<h1>Vaartijden Duinkerken naar Dover<\/h1>\n\t\t<p class=\"dd-lede\">DFDS vaart overdag ongeveer elke twee uur, met enkele nacht- en vroege-ochtendafvaarten, in beide richtingen. Hieronder staan de afvaarten van vandaag, het overzicht voor de komende week en de tijden waarop het inchecken sluit. Vertrektijden zijn in de lokale tijd van de vertrekhaven.<\/p>\n\t\t<div class=\"dd-meta\"><span class=\"dd-updated\"><svg class=\"dd-ic\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"9\"\/><path d=\"M12 7v5l3 2\"\/><\/svg>Bijgewerkt 28 september 2026<\/span><span class=\"dd-small dd-muted\">Bron: dienstregeling DFDS via DirectFerries, elke minuut ververst<\/span><\/div>\n\t<\/div>\n\n\t<div class=\"dd-page\">\n\t\t<div class=\"dd-main\">\n\t\t\t<section id=\"vandaag\">\n\t\t\t\t<h2>Afvaarten vandaag<\/h2>\n\t\t\t\t<p>Beide richtingen, met de tijd waarop het inchecken sluit. Vertrek en aankomst staan in de lokale tijd van de haven.<\/p>\n\t\t\t\t<section class=\"dd-board dd-board--full\" aria-label=\"Afvaarten vandaag\"><div class=\"dd-board__head\"><p class=\"dd-board__title\">Afvaarten vandaag<\/p><span class=\"dd-board__live\"><i><\/i>Live <span class=\"dd-board__upd\">\u00b7 bijgewerkt 00:56<\/span><\/span><\/div><div class=\"dd-board__clocks\"><div class=\"dd-board__clock\" data-tz=\"Europe\/Paris\"><span class=\"dd-board__port\">Duinkerken<\/span><span class=\"dd-board__time dd-num\" data-dd-clock>01:56<\/span><span class=\"dd-board__zone\" data-dd-zone>CEST<\/span><\/div><div class=\"dd-board__mid\">2 uur varen<br>Frankrijk +1 uur<\/div><div class=\"dd-board__clock is-right\" data-tz=\"Europe\/London\"><span class=\"dd-board__port\">Dover<\/span><span class=\"dd-board__time dd-num\" data-dd-clock>00:56<\/span><span class=\"dd-board__zone\" data-dd-zone>BST<\/span><\/div><\/div><div class=\"dd-board__pane is-on\" id=\"dd-pane-99\" role=\"tabpanel\" aria-labelledby=\"dd-tab-99\"><h3 class=\"dd-board__pane-title\">Duinkerken \u2192 Dover<\/h3><table class=\"dd-board__table\"><thead><tr><th>Vertrek<\/th><th>Aankomst<\/th><th>Inchecken v\u00f3\u00f3r<\/th><th><\/th><\/tr><\/thead><tbody><tr class=\"is-next\"><td class=\"dd-board__dep dd-num\">04:00<\/td><td class=\"dd-board__arr dd-num\">05:00<\/td><td class=\"dd-board__chk dd-num\">03:00<\/td><td class=\"dd-board__st\"><span class=\"dd-pill dd-pill--next\"><i><\/i>Volgende<\/span><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">06:00<\/td><td class=\"dd-board__arr dd-num\">07:00<\/td><td class=\"dd-board__chk dd-num\">05:00<\/td><td class=\"dd-board__st\"><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">08:00<\/td><td class=\"dd-board__arr dd-num\">09:00<\/td><td class=\"dd-board__chk dd-num\">07:00<\/td><td class=\"dd-board__st\"><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">10:00<\/td><td class=\"dd-board__arr dd-num\">11:00<\/td><td class=\"dd-board__chk dd-num\">09:00<\/td><td class=\"dd-board__st\"><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">12:00<\/td><td class=\"dd-board__arr dd-num\">13:00<\/td><td class=\"dd-board__chk dd-num\">11:00<\/td><td class=\"dd-board__st\"><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">14:00<\/td><td class=\"dd-board__arr dd-num\">15:00<\/td><td class=\"dd-board__chk dd-num\">13:00<\/td><td class=\"dd-board__st\"><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">16:00<\/td><td class=\"dd-board__arr dd-num\">17:00<\/td><td class=\"dd-board__chk dd-num\">15:00<\/td><td class=\"dd-board__st\"><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">18:00<\/td><td class=\"dd-board__arr dd-num\">19:00<\/td><td class=\"dd-board__chk dd-num\">17:00<\/td><td class=\"dd-board__st\"><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">20:00<\/td><td class=\"dd-board__arr dd-num\">21:00<\/td><td class=\"dd-board__chk dd-num\">19:00<\/td><td class=\"dd-board__st\"><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">23:59<\/td><td class=\"dd-board__arr dd-num\">00:59<\/td><td class=\"dd-board__chk dd-num\">22:59<\/td><td class=\"dd-board__st\"><\/td><\/tr><\/tbody><\/table><\/div><div class=\"dd-board__pane\" id=\"dd-pane-100\" role=\"tabpanel\" aria-labelledby=\"dd-tab-100\"><h3 class=\"dd-board__pane-title\">Dover \u2192 Duinkerken<\/h3><table class=\"dd-board__table\"><thead><tr><th>Vertrek<\/th><th>Aankomst<\/th><th>Inchecken v\u00f3\u00f3r<\/th><th><\/th><\/tr><\/thead><tbody><tr class=\"is-next\"><td class=\"dd-board__dep dd-num\">06:00<\/td><td class=\"dd-board__arr dd-num\">09:00<\/td><td class=\"dd-board__chk dd-num\">05:00<\/td><td class=\"dd-board__st\"><span class=\"dd-pill dd-pill--next\"><i><\/i>Volgende<\/span><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">08:00<\/td><td class=\"dd-board__arr dd-num\">11:00<\/td><td class=\"dd-board__chk dd-num\">07:00<\/td><td class=\"dd-board__st\"><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">10:00<\/td><td class=\"dd-board__arr dd-num\">13:00<\/td><td class=\"dd-board__chk dd-num\">09:00<\/td><td class=\"dd-board__st\"><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">12:00<\/td><td class=\"dd-board__arr dd-num\">15:00<\/td><td class=\"dd-board__chk dd-num\">11:00<\/td><td class=\"dd-board__st\"><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">14:00<\/td><td class=\"dd-board__arr dd-num\">17:00<\/td><td class=\"dd-board__chk dd-num\">13:00<\/td><td class=\"dd-board__st\"><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">16:00<\/td><td class=\"dd-board__arr dd-num\">19:00<\/td><td class=\"dd-board__chk dd-num\">15:00<\/td><td class=\"dd-board__st\"><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">18:00<\/td><td class=\"dd-board__arr dd-num\">21:00<\/td><td class=\"dd-board__chk dd-num\">17:00<\/td><td class=\"dd-board__st\"><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">20:00<\/td><td class=\"dd-board__arr dd-num\">23:00<\/td><td class=\"dd-board__chk dd-num\">19:00<\/td><td class=\"dd-board__st\"><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">22:00<\/td><td class=\"dd-board__arr dd-num\">01:00<\/td><td class=\"dd-board__chk dd-num\">21:00<\/td><td class=\"dd-board__st\"><\/td><\/tr><\/tbody><\/table><\/div><div class=\"dd-board__foot\"><span>Vertrek in lokale tijd van de vertrekhaven, aankomst in lokale tijd van de aankomsthaven.<\/span><\/div><\/section>\n\t\t\t<\/section>\n\n\t\t\t<section id=\"week\">\n\t\t\t\t<h2>Vaartijden komende week: boot Duinkerken naar Dover<\/h2>\n\t\t\t\t<p>Per dag het aantal afvaarten en de vertrektijden in Franse tijd. Op weekdagen zijn er meestal tien afvaarten, in het weekend minder; de nachtafvaart van 23:59 vaart niet elke dag.<\/p>\n\t\t\t\t<div class=\"dd-panel dd-tw\"><table class=\"dd-table dd-week\"><thead><tr><th>Dag<\/th><th>Afvaarten<\/th><th>Vertrektijden, lokale tijd<\/th><\/tr><\/thead><tbody><tr class=\"is-today\"><th scope=\"row\">ma 5-10<\/th><td><span class=\"dd-week__n dd-num\">10<\/span><\/td><td class=\"dd-week__times\"><span class=\"dd-week__t dd-num\">04:00<\/span><span class=\"dd-week__t dd-num\">06:00<\/span><span class=\"dd-week__t dd-num\">08:00<\/span><span class=\"dd-week__t dd-num\">10:00<\/span><span class=\"dd-week__t dd-num\">12:00<\/span><span class=\"dd-week__t dd-num\">14:00<\/span><span class=\"dd-week__t dd-num\">16:00<\/span><span class=\"dd-week__t dd-num\">18:00<\/span><span class=\"dd-week__t dd-num\">20:00<\/span><span class=\"dd-week__t dd-num\">23:59<\/span><\/td><\/tr><tr><th scope=\"row\">di 6-10<\/th><td><span class=\"dd-week__n dd-num\">10<\/span><\/td><td class=\"dd-week__times\"><span class=\"dd-week__t dd-num\">04:00<\/span><span class=\"dd-week__t dd-num\">06:00<\/span><span class=\"dd-week__t dd-num\">08:00<\/span><span class=\"dd-week__t dd-num\">10:00<\/span><span class=\"dd-week__t dd-num\">12:00<\/span><span class=\"dd-week__t dd-num\">14:00<\/span><span class=\"dd-week__t dd-num\">16:00<\/span><span class=\"dd-week__t dd-num\">18:00<\/span><span class=\"dd-week__t dd-num\">20:00<\/span><span class=\"dd-week__t dd-num\">23:59<\/span><\/td><\/tr><tr><th scope=\"row\">wo 7-10<\/th><td><span class=\"dd-week__n dd-num\">10<\/span><\/td><td class=\"dd-week__times\"><span class=\"dd-week__t dd-num\">04:00<\/span><span class=\"dd-week__t dd-num\">06:00<\/span><span class=\"dd-week__t dd-num\">08:00<\/span><span class=\"dd-week__t dd-num\">10:00<\/span><span class=\"dd-week__t dd-num\">12:00<\/span><span class=\"dd-week__t dd-num\">14:00<\/span><span class=\"dd-week__t dd-num\">16:00<\/span><span class=\"dd-week__t dd-num\">18:00<\/span><span class=\"dd-week__t dd-num\">20:00<\/span><span class=\"dd-week__t dd-num\">23:59<\/span><\/td><\/tr><tr><th scope=\"row\">do 8-10<\/th><td><span class=\"dd-week__n dd-num\">10<\/span><\/td><td class=\"dd-week__times\"><span class=\"dd-week__t dd-num\">04:00<\/span><span class=\"dd-week__t dd-num\">06:00<\/span><span class=\"dd-week__t dd-num\">08:00<\/span><span class=\"dd-week__t dd-num\">10:00<\/span><span class=\"dd-week__t dd-num\">12:00<\/span><span class=\"dd-week__t dd-num\">14:00<\/span><span class=\"dd-week__t dd-num\">16:00<\/span><span class=\"dd-week__t dd-num\">18:00<\/span><span class=\"dd-week__t dd-num\">20:00<\/span><span class=\"dd-week__t dd-num\">23:59<\/span><\/td><\/tr><tr><th scope=\"row\">vr 9-10<\/th><td><span class=\"dd-week__n dd-num\">9<\/span><\/td><td class=\"dd-week__times\"><span class=\"dd-week__t dd-num\">04:00<\/span><span class=\"dd-week__t dd-num\">06:00<\/span><span class=\"dd-week__t dd-num\">08:00<\/span><span class=\"dd-week__t dd-num\">10:00<\/span><span class=\"dd-week__t dd-num\">12:00<\/span><span class=\"dd-week__t dd-num\">14:00<\/span><span class=\"dd-week__t dd-num\">16:00<\/span><span class=\"dd-week__t dd-num\">18:00<\/span><span class=\"dd-week__t dd-num\">20:00<\/span><\/td><\/tr><tr><th scope=\"row\">za 10-10<\/th><td><span class=\"dd-week__n dd-num\">8<\/span><\/td><td class=\"dd-week__times\"><span class=\"dd-week__t dd-num\">04:00<\/span><span class=\"dd-week__t dd-num\">06:00<\/span><span class=\"dd-week__t dd-num\">08:00<\/span><span class=\"dd-week__t dd-num\">10:00<\/span><span class=\"dd-week__t dd-num\">12:00<\/span><span class=\"dd-week__t dd-num\">14:00<\/span><span class=\"dd-week__t dd-num\">16:00<\/span><span class=\"dd-week__t dd-num\">20:00<\/span><\/td><\/tr><tr><th scope=\"row\">zo 11-10<\/th><td><span class=\"dd-week__n dd-num\">7<\/span><\/td><td class=\"dd-week__times\"><span class=\"dd-week__t dd-num\">06:00<\/span><span class=\"dd-week__t dd-num\">10:00<\/span><span class=\"dd-week__t dd-num\">12:00<\/span><span class=\"dd-week__t dd-num\">14:00<\/span><span class=\"dd-week__t dd-num\">16:00<\/span><span class=\"dd-week__t dd-num\">18:00<\/span><span class=\"dd-week__t dd-num\">20:00<\/span><\/td><\/tr><\/tbody><\/table><\/div>\n\t\t\t<\/section>\n\n\t\t\t<section id=\"week-terug\">\n\t\t\t\t<h2>Vaartijden komende week: boot Dover naar Duinkerken<\/h2>\n\t\t\t\t<p>Vertrektijden in Engelse tijd. De aankomst in Duinkerken staat op je ticket drie uur later: twee uur varen plus het uur tijdsverschil.<\/p>\n\t\t\t\t<div class=\"dd-panel dd-tw\"><table class=\"dd-table dd-week\"><thead><tr><th>Dag<\/th><th>Afvaarten<\/th><th>Vertrektijden, lokale tijd<\/th><\/tr><\/thead><tbody><tr class=\"is-today\"><th scope=\"row\">ma 5-10<\/th><td><span class=\"dd-week__n dd-num\">9<\/span><\/td><td class=\"dd-week__times\"><span class=\"dd-week__t dd-num\">06:00<\/span><span class=\"dd-week__t dd-num\">08:00<\/span><span class=\"dd-week__t dd-num\">10:00<\/span><span class=\"dd-week__t dd-num\">12:00<\/span><span class=\"dd-week__t dd-num\">14:00<\/span><span class=\"dd-week__t dd-num\">16:00<\/span><span class=\"dd-week__t dd-num\">18:00<\/span><span class=\"dd-week__t dd-num\">20:00<\/span><span class=\"dd-week__t dd-num\">22:00<\/span><\/td><\/tr><tr><th scope=\"row\">di 6-10<\/th><td><span class=\"dd-week__n dd-num\">10<\/span><\/td><td class=\"dd-week__times\"><span class=\"dd-week__t dd-num\">02:00<\/span><span class=\"dd-week__t dd-num\">06:00<\/span><span class=\"dd-week__t dd-num\">08:00<\/span><span class=\"dd-week__t dd-num\">10:00<\/span><span class=\"dd-week__t dd-num\">12:00<\/span><span class=\"dd-week__t dd-num\">14:00<\/span><span class=\"dd-week__t dd-num\">16:00<\/span><span class=\"dd-week__t dd-num\">18:00<\/span><span class=\"dd-week__t dd-num\">20:00<\/span><span class=\"dd-week__t dd-num\">22:00<\/span><\/td><\/tr><tr><th scope=\"row\">wo 7-10<\/th><td><span class=\"dd-week__n dd-num\">10<\/span><\/td><td class=\"dd-week__times\"><span class=\"dd-week__t dd-num\">02:00<\/span><span class=\"dd-week__t dd-num\">06:00<\/span><span class=\"dd-week__t dd-num\">08:00<\/span><span class=\"dd-week__t dd-num\">10:00<\/span><span class=\"dd-week__t dd-num\">12:00<\/span><span class=\"dd-week__t dd-num\">14:00<\/span><span class=\"dd-week__t dd-num\">16:00<\/span><span class=\"dd-week__t dd-num\">18:00<\/span><span class=\"dd-week__t dd-num\">20:00<\/span><span class=\"dd-week__t dd-num\">22:00<\/span><\/td><\/tr><tr><th scope=\"row\">do 8-10<\/th><td><span class=\"dd-week__n dd-num\">10<\/span><\/td><td class=\"dd-week__times\"><span class=\"dd-week__t dd-num\">02:00<\/span><span class=\"dd-week__t dd-num\">06:00<\/span><span class=\"dd-week__t dd-num\">08:00<\/span><span class=\"dd-week__t dd-num\">10:00<\/span><span class=\"dd-week__t dd-num\">12:00<\/span><span class=\"dd-week__t dd-num\">14:00<\/span><span class=\"dd-week__t dd-num\">16:00<\/span><span class=\"dd-week__t dd-num\">18:00<\/span><span class=\"dd-week__t dd-num\">20:00<\/span><span class=\"dd-week__t dd-num\">22:00<\/span><\/td><\/tr><tr><th scope=\"row\">vr 9-10<\/th><td><span class=\"dd-week__n dd-num\">10<\/span><\/td><td class=\"dd-week__times\"><span class=\"dd-week__t dd-num\">02:00<\/span><span class=\"dd-week__t dd-num\">06:00<\/span><span class=\"dd-week__t dd-num\">08:00<\/span><span class=\"dd-week__t dd-num\">10:00<\/span><span class=\"dd-week__t dd-num\">12:00<\/span><span class=\"dd-week__t dd-num\">14:00<\/span><span class=\"dd-week__t dd-num\">16:00<\/span><span class=\"dd-week__t dd-num\">18:00<\/span><span class=\"dd-week__t dd-num\">20:00<\/span><span class=\"dd-week__t dd-num\">22:00<\/span><\/td><\/tr><tr><th scope=\"row\">za 10-10<\/th><td><span class=\"dd-week__n dd-num\">8<\/span><\/td><td class=\"dd-week__times\"><span class=\"dd-week__t dd-num\">06:00<\/span><span class=\"dd-week__t dd-num\">08:00<\/span><span class=\"dd-week__t dd-num\">10:00<\/span><span class=\"dd-week__t dd-num\">12:00<\/span><span class=\"dd-week__t dd-num\">14:00<\/span><span class=\"dd-week__t dd-num\">16:00<\/span><span class=\"dd-week__t dd-num\">18:00<\/span><span class=\"dd-week__t dd-num\">22:00<\/span><\/td><\/tr><tr><th scope=\"row\">zo 11-10<\/th><td><span class=\"dd-week__n dd-num\">7<\/span><\/td><td class=\"dd-week__times\"><span class=\"dd-week__t dd-num\">08:00<\/span><span class=\"dd-week__t dd-num\">12:00<\/span><span class=\"dd-week__t dd-num\">14:00<\/span><span class=\"dd-week__t dd-num\">16:00<\/span><span class=\"dd-week__t dd-num\">18:00<\/span><span class=\"dd-week__t dd-num\">20:00<\/span><span class=\"dd-week__t dd-num\">22:00<\/span><\/td><\/tr><\/tbody><\/table><\/div>\n\t\t\t<\/section>\n\n\t\t\t<section id=\"datum\">\n\t\t\t\t<h2>Een andere datum kiezen<\/h2>\n\t\t\t\t<p>Kies een datum en het aantal dagen; de tijden komen rechtstreeks uit de dienstregeling. Voor de prijs op die dag ga je naar <a href=\"https:\/\/dover-dunkirk.com\/nl\/prijzen-duinkerken-dover\/\">prijzen en boeken<\/a>.<\/p>\n\t\t\t\t<h3>Duinkerken naar Dover<\/h3>\n\t\t\t\t<div class=\"tp-wrap tp-theme-extended_cards tp-day-setup-modern\" data-config=\"{&quot;rest&quot;:&quot;https:\\\/\\\/dover-dunkirk.com\\\/nl\\\/wp-json\\\/timetables-pro\\\/v1\\\/timetables&quot;,&quot;routes&quot;:[99],&quot;days&quot;:1,&quot;autoload&quot;:true,&quot;theme&quot;:&quot;extended_cards&quot;,&quot;daySetup&quot;:&quot;modern&quot;,&quot;limit10&quot;:false,&quot;routeLabels&quot;:{&quot;99&quot;:&quot;Duinkerken-Dover&quot;},&quot;opFilter&quot;:[&quot;6&quot;],&quot;labels&quot;:{&quot;ui_date&quot;:&quot;Datum&quot;,&quot;ui_days&quot;:&quot;Dagen&quot;,&quot;ui_button&quot;:&quot;Afvaarten tonen&quot;,&quot;status_idle&quot;:&quot;Kies een datum en klik op Afvaarten tonen&quot;,&quot;status_loading&quot;:&quot;Laden...&quot;,&quot;status_empty&quot;:&quot;Geen afvaarten gevonden&quot;,&quot;status_found&quot;:&quot;%d afvaarten gevonden&quot;,&quot;th_date&quot;:&quot;Datum&quot;,&quot;th_dep&quot;:&quot;Vertrek&quot;,&quot;th_arr&quot;:&quot;Aankomst&quot;,&quot;th_dur&quot;:&quot;Duur&quot;,&quot;th_ship&quot;:&quot;Schip&quot;,&quot;th_op&quot;:&quot;Operator&quot;,&quot;th_route&quot;:&quot;Route&quot;,&quot;wd_sun&quot;:&quot;ZO&quot;,&quot;wd_mon&quot;:&quot;MA&quot;,&quot;wd_tue&quot;:&quot;DI&quot;,&quot;wd_wed&quot;:&quot;WO&quot;,&quot;wd_thu&quot;:&quot;DO&quot;,&quot;wd_fri&quot;:&quot;VR&quot;,&quot;wd_sat&quot;:&quot;ZA&quot;,&quot;summary_footer_one&quot;:&quot;\\u00bb Bekijk alle %s afvaarten in onze dienstregeling&quot;,&quot;summary_footer_two&quot;:&quot;\\u00bb Bekijk meer %1$s en %2$s afvaarten in onze dienstregeling&quot;,&quot;summary_footer_generic&quot;:&quot;Bekijk onze dienstregeling voor meer afvaarten&quot;,&quot;summary_header&quot;:&quot;De volgende twee afvaarten:&quot;,&quot;summary_no_upcoming&quot;:&quot;Geen aankomende afvaarten gevonden&quot;,&quot;more_link&quot;:&quot;Meer afvaarten&quot;,&quot;more_departures_button&quot;:&quot;Meer afvaarten tonen&quot;,&quot;day_nav_previous&quot;:&quot;Vorige dag tonen&quot;,&quot;day_nav_next&quot;:&quot;Volgende dag tonen&quot;,&quot;day_nav_today&quot;:&quot;Vandaag tonen&quot;,&quot;day_nav_tomorrow&quot;:&quot;Morgen tonen&quot;,&quot;local_time_pair&quot;:&quot;Lokale tijd vertrekhaven: %1$s \\\/ Lokale tijd aankomsthaven: %2$s&quot;,&quot;local_time_combined&quot;:&quot;Lokale tijd vertrek- en aankomsthaven: %s&quot;,&quot;tag_often_booked&quot;:&quot;\\u2b50 Vaak geboekt&quot;,&quot;tag_leaving_soon&quot;:&quot;\\ud83d\\udd34 Vertrekt binnenkort&quot;,&quot;tag_currently_sailing&quot;:&quot;\\ud83d\\udfe2 Nu onderweg&quot;,&quot;tag_arrived&quot;:&quot;\\u26ab Aangekomen&quot;,&quot;tag_overnight&quot;:&quot;Nachtvaart&quot;},&quot;showLogo&quot;:true,&quot;activityBoosters&quot;:true,&quot;title&quot;:&quot;&quot;,&quot;shipMap&quot;:[],&quot;shipLinks&quot;:[],&quot;showShip&quot;:false,&quot;departurePort&quot;:&quot;Dunkirk&quot;,&quot;arrivalPort&quot;:&quot;Dover&quot;,&quot;departureTimezone&quot;:&quot;Europe\\\/Paris&quot;,&quot;arrivalTimezone&quot;:&quot;Europe\\\/London&quot;}\">\n  <div class=\"tp-controls\" role=\"group\" aria-label=\"Timetable controls\">\n    <div>\n      <label for=\"tp-date-ops\">Datum<\/label><br>\n      <input id=\"tp-date-ops\" class=\"tp-date\" type=\"date\" aria-label=\"Datum\">\n    <\/div>\n    <div class=\"tp-day-field\">\n      <label for=\"tp-range-ops\">Dagen<\/label><br>\n      <select id=\"tp-range-ops\" class=\"tp-range\" aria-label=\"Dagen\">\n        <option value=\"1\">1<\/option><option value=\"3\">3<\/option><option value=\"7\">7<\/option><option value=\"14\">14<\/option>\n      <\/select>\n    <\/div>\n    <div><button id=\"tp-load-ops\" class=\"tp-btn\">Afvaarten tonen<\/button><\/div>\n  <\/div>\n\n  <div class=\"tp-local-nav-row\">\n    <div class=\"tp-local-times\" id=\"tp-local-times-ops\" aria-live=\"polite\"><\/div>\n    <div class=\"tp-day-nav-host\"><\/div>\n  <\/div>\n\n  \n  <div id=\"tp-status-ops\" class=\"tp-muted\" aria-live=\"polite\">Kies een datum en klik op Afvaarten tonen<\/div>\n\n  <div id=\"tp-ops-results\"><\/div>\n\n  <div class=\"tp-loader\" aria-hidden=\"true\">\n    <div class=\"tp-loader-card\">\n      <div class=\"tp-spinner\" aria-hidden=\"true\"><\/div>\n      <div class=\"tp-loader-text\">Laden...<\/div>\n    <\/div>\n  <\/div>\n<\/div>\n\n<script>\n(function(){\n  const wrap   = document.currentScript.previousElementSibling;\n  const cfg    = JSON.parse(wrap.getAttribute('data-config')||'{}');\n  const L      = cfg.labels||{};\n  const dateEl = wrap.querySelector('#tp-date-ops');\n  const daysEl = wrap.querySelector('#tp-range-ops');\n  const btn    = wrap.querySelector('#tp-load-ops');\n  const status = wrap.querySelector('#tp-status-ops');\n  const out    = wrap.querySelector('#tp-ops-results');\n  const loader = wrap.querySelector('.tp-loader');\n  const navHost = wrap.querySelector('.tp-day-nav-host');\n  const localTimesEl = wrap.querySelector('#tp-local-times-ops');\n\n  const showShip = (cfg.showShip !== false && cfg.showShip !== 0 && cfg.showShip !== '0');\n  const activityBoosters = !!cfg.activityBoosters;\n  const daySetup = (cfg.daySetup === 'modern') ? 'modern' : 'classic';\n  const limit10 = !!cfg.limit10;\n  let featuredKey = '';\n  let soonKey = '';\n  let revealAll = false;\n\n  if (daySetup === 'modern') {\n    const dayField = wrap.querySelector('.tp-day-field');\n    if (dayField) dayField.style.display = 'none';\n  }\n\n  dateEl.valueAsDate = new Date();\n  dateEl.min = new Date().toISOString().split('T')[0];\n  Array.from(daysEl.options).forEach(o=>{ if(parseInt(o.value,10)===parseInt(cfg.days||7,10)) o.selected=true; });\n\n  function pad(n){ return String(n).padStart(2,'0'); }\n  function iso(d){ return d.getFullYear()+'-'+pad(d.getMonth()+1)+'-'+pad(d.getDate()); }\n  function toLocal(s){ return new Date(s); }\n  function hhmm(d){ return d.toLocaleTimeString([], {hour:'2-digit', minute:'2-digit'}); }\n  function dShort(d){ return d.toLocaleDateString([], {day:'numeric', month:'short'}); }\n  function dur(m){ const h=Math.floor(m\/60), r=m%60; return r? (h+'h '+r+'m') : (h+'h'); }\n\n  const WD = [\n    L.wd_sun || 'SUN',\n    L.wd_mon || 'MON',\n    L.wd_tue || 'TUE',\n    L.wd_wed || 'WED',\n    L.wd_thu || 'THU',\n    L.wd_fri || 'FRI',\n    L.wd_sat || 'SAT'\n  ];\n\n  function setLoader(v){ loader.classList.toggle('show', !!v); loader.setAttribute('aria-hidden', v?'false':'true'); }\n\n  function formatZoneTime(tz){\n    if (!tz) return '--:--';\n    try {\n      return new Intl.DateTimeFormat([], {hour:'2-digit', minute:'2-digit', hour12:false, timeZone: tz}).format(new Date());\n    } catch (e) {\n      return '--:--';\n    }\n  }\n\n  function renderLocalTimes(){\n    if (!localTimesEl) return;\n    if (!cfg.departureTimezone || !cfg.arrivalTimezone) {\n      localTimesEl.textContent = '';\n      return;\n    }\n    const depTime = formatZoneTime(cfg.departureTimezone);\n    const arrTime = formatZoneTime(cfg.arrivalTimezone);\n    const pairTpl = L.local_time_pair || 'Departure Port Local Time: %1$s \/ Arrival Port Local Time: %2$s';\n    const combinedTpl = L.local_time_combined || 'Departure & Arrival Port Local Time: %s';\n    if (depTime === arrTime) {\n      localTimesEl.textContent = combinedTpl.replace('%s', depTime);\n      return;\n    }\n    localTimesEl.textContent = pairTpl.replace('%1$s', depTime).replace('%2$s', arrTime);\n  }\n\n  function setStatusInline(html){\n    let box = wrap.querySelector('.tp-controls-status');\n    if (!box) {\n      box = document.createElement('div');\n      box.className = 'tp-controls-status';\n      wrap.querySelector('.tp-controls').appendChild(box);\n    }\n    box.innerHTML = html || '';\n  }\n\n  function clearStatusInline(){\n    const box = wrap.querySelector('.tp-controls-status');\n    if (box) box.innerHTML = '';\n  }\n\n  function navHtml(){\n    if (daySetup !== 'modern') return '';\n    const base = new Date(dateEl.value || new Date());\n    const today = new Date();\n    const tomorrow = new Date(today);\n    tomorrow.setDate(today.getDate() + 1);\n    const isToday = base.toDateString() === today.toDateString();\nlet prevLabel = L.day_nav_previous || 'Show previous day';\nlet nextLabel = L.day_nav_next || 'Show next day';\nif (isToday) nextLabel = L.day_nav_tomorrow || 'Show tomorrow';\nif (base.toDateString() === tomorrow.toDateString()) prevLabel = L.day_nav_today || 'Show today';\n    return '<div class=\"tp-day-nav\">'\n      + (isToday ? '' : '<a href=\"#\" data-shift=\"-1\">'+prevLabel+'<\/a>')\n      + '<a href=\"#\" data-shift=\"1\">'+nextLabel+'<\/a>'\n      + '<\/div>';\n  }\n\n  function shiftDate(delta){\n    const base = new Date(dateEl.value || new Date());\n    base.setDate(base.getDate() + delta);\n    dateEl.value = iso(base);\n    load();\n  }\n\n  function moreButtonHtml(hiddenCount){\n    if (!limit10 || revealAll || hiddenCount <= 0) return '';\n    return '<div style=\"margin-top:12px;text-align:center\">'\n      + '<button type=\"button\" class=\"tp-btn tp-more-btn\">'+(L.more_departures_button || 'Show more departures')+' ('+hiddenCount+')<\/button>'\n      + '<\/div>';\n  }\n\n  function opCell(r){\n    const name = r.opName || ('Operator '+(r.opId||''));\n    const logo = (cfg.showLogo && r.opLogo) ? '<img decoding=\"async\" src=\"'+r.opLogo+'\" alt=\"'+name+'\"> ' : '';\n    const label = logo + '<span>'+name+'<\/span>';\n    return r.opLink ? '<a class=\"tp-op\" href=\"'+r.opLink+'\" target=\"_blank\" rel=\"nofollow noopener\">'+label+'<\/a>' : '<span class=\"tp-op\">'+label+'<\/span>';\n  }\n\n  function shipInfo(original){\n    const key = (original||'').toLowerCase().trim();\n    const label = (cfg.shipMap && cfg.shipMap[key]) || original || '';\n    const href  = (cfg.shipLinks && cfg.shipLinks[key]) || '';\n    return {label, href};\n  }\n\n  function shipBadge(original){\n    const s = shipInfo(original);\n    const badge = '<span class=\"tp-badge\">'+(s.label||'')+'<\/span>';\n    return s.href ? ('<a href=\"'+s.href+'\" target=\"_blank\" rel=\"nofollow noopener\">'+badge+'<\/a>') : badge;\n  }\n\n  function rowKey(r){\n    return [String(r.routeId||''), String(r.opId||''), String(+r.dep||0), String(+r.arr||0)].join('|');\n  }\n\n  function pickFeaturedKey(rows, avoidKey){\n    if (!activityBoosters || !rows.length) return '';\n    const routesSum = Array.isArray(cfg.routes) ? cfg.routes.reduce((acc, n)=>acc + (parseInt(n,10)||0), 0) : 0;\n    const dateSeed = parseInt(String(dateEl.value || '').replace(\/-\/g,''), 10) || 0;\n\n    let pool = rows;\n    if (avoidKey) {\n      const soonIdx = rows.findIndex(r => rowKey(r) === avoidKey);\n      if (soonIdx >= 0) {\n        const later = rows.slice(soonIdx + 1).filter(r => rowKey(r) !== avoidKey);\n        pool = later.length ? later : rows.filter(r => rowKey(r) !== avoidKey);\n      } else {\n        pool = rows.filter(r => rowKey(r) !== avoidKey);\n      }\n    }\n\n    if (!pool.length) return '';\n    const idx = Math.abs((routesSum + dateSeed + rows.length) % pool.length);\n    return rowKey(pool[idx]);\n  }\n\n  function pickSoonKey(rows){\n    if (!activityBoosters || !rows.length) return '';\n    const now = Date.now();\n    const todayStr = new Date(now).toDateString();\n    const firstUpcoming = rows.find(r => (r.dep instanceof Date) && r.dep.getTime() > now && r.dep.toDateString() === todayStr);\n    return firstUpcoming ? rowKey(firstUpcoming) : '';\n  }\n\n  function boostersFor(r){\n    if (!activityBoosters) return [];\n    const now = Date.now();\n    const depMs = (r.dep instanceof Date) ? r.dep.getTime() : 0;\n    const arrMs = (r.arr instanceof Date) ? r.arr.getTime() : 0;\n    const depIsToday = (r.dep instanceof Date) && (new Date(now).toDateString() === r.dep.toDateString());\n\n    if (depMs > 0 && arrMs > 0 && depMs <= now && arrMs > now) {\n      return [{cls:'tp-booster-sailing', text:(L.tag_currently_sailing || '\ud83d\udfe2 Currently sailing')}];\n    }\n    if (depIsToday && arrMs > 0 && arrMs <= now) {\n      return [{cls:'tp-booster-arrived', text:(L.tag_arrived || '\u26ab Arrived')}];\n    }\n    if (rowKey(r) === soonKey) return [{cls:'tp-booster-soon', text:(L.tag_leaving_soon || '\ud83d\udd34 Leaving soon')}];\n    if (r.dep && r.arr && r.dep.toDateString() !== r.arr.toDateString()) return [{cls:'tp-booster-overnight', text:(L.tag_overnight || 'Overnight')}];\n\n    return [];\n  }\n\n  function boostersHtml(r, floating){\n    const tags = boostersFor(r);\n    if (!tags.length) return '';\n    const cls = floating ? 'tp-boosters tp-boosters-float' : 'tp-boosters';\n    return '<div class=\"'+cls+'\">' + tags.map(t => '<span class=\"tp-booster '+t.cls+'\">'+boosterLabelHtml(t.text)+'<\/span>').join('') + '<\/div>';\n  }\n\n  function boosterLabelHtml(text){\n    return String(text || '').replace(\/^(\ud83d\udd34|\ud83d\udfe2|\u26ab|\u2b50)\\s*\/, '<span class=\"tp-booster-emoji\">$1<\/span>');\n  }\n\n  function routeTicketHtml(label){\n    const raw = String(label || '').trim();\n    if (!raw) return '';\n    if (cfg.theme !== 'small_cards') return escAttr(raw);\n    const parts = raw.split(\/\\s*[\\-\u2013]\\s*\/, 2);\n    if (parts.length < 2) return escAttr(raw);\n    return escAttr(parts[0]) + '<br>' + escAttr(parts[1]);\n  }\n\n  function escAttr(v){\n    return String(v||'').replace(\/[&<>\"']\/g, m => ({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'}[m]));\n  }\n\n  function bindRowLinks(){\n    if (cfg.theme !== 'max_clickouts') return;\n    out.querySelectorAll('tr.tp-row-link').forEach((row)=>{\n      row.setAttribute('role','link');\n      row.setAttribute('tabindex','0');\n      row.addEventListener('click', (e)=>{\n        if (e.target && e.target.closest('a')) return;\n        const href = row.getAttribute('data-row-link');\n        if (!href) return;\n        window.open(href, '_blank', 'noopener,noreferrer');\n      });\n      row.addEventListener('keydown', (e)=>{\n        if (e.key !== 'Enter' && e.key !== ' ') return;\n        e.preventDefault();\n        row.click();\n      });\n    });\n  }\n\n  function routeLabel(rid){\n    return (cfg.routeLabels && (cfg.routeLabels[String(rid)] || cfg.routeLabels[rid])) || String(rid);\n  }\n\n  function renderTable(rows){\n    const th = {date:L.th_date,dep:L.th_dep,arr:L.th_arr,dur:L.th_dur,ship:L.th_ship,route:L.th_route,op:L.th_op};\n\n    const headCells = [\n      '<th>'+th.date+'<\/th>',\n      '<th>'+th.dep+'<\/th>',\n      '<th>'+th.arr+'<\/th>',\n      '<th>'+th.dur+'<\/th>'\n    ];\n    if (showShip) {\n      headCells.push('<th>'+th.ship+'<\/th>');\n    }\n    headCells.push('<th>'+th.route+'<\/th>');\n    headCells.push('<th>'+th.op+'<\/th>');\n\n    let html = '<table class=\"tp-table\"><thead><tr>'+headCells.join('')+'<\/tr><\/thead><tbody>';\n    rows.forEach(r=>{\n      const dow = WD[r.dep.getDay()] || '';\n      const clickable = (cfg.theme === 'max_clickouts' && r.opLink);\n      const rowAttr = clickable ? (' class=\"tp-row-link\" data-row-link=\"'+escAttr(r.opLink)+'\"') : '';\n      const dateBoosters = (cfg.theme === 'max_clickouts') ? '' : boostersHtml(r, false);\n      const routeBoosters = (cfg.theme === 'max_clickouts') ? boostersHtml(r, false) : '';\n      const cells = [\n        '<td>'+dShort(r.dep)+' <span class=\"tp-day\">'+dow+'<\/span>'+dateBoosters+'<\/td>',\n        '<td>'+hhmm(r.dep)+'<\/td>',\n        '<td>'+hhmm(r.arr)+'<\/td>',\n        '<td>'+dur(r.min)+'<\/td>'\n      ];\n      if (showShip) {\n        cells.push('<td>'+shipBadge(r.ship)+'<\/td>');\n      }\n      cells.push('<td>'+routeBoosters+'<div>'+routeLabel(r.routeId)+'<\/div><\/td>');\n      cells.push('<td>'+opCell(r)+'<\/td>');\n      html += '<tr'+rowAttr+'>'+cells.join('')+'<\/tr>';\n    });\n    html += '<\/tbody><\/table>';\n    return html;\n  }\n\n  function renderCards(rows){\n    if (cfg.theme === 'extended_cards') {\n      return renderExtendedCards(rows);\n    }\n\n    let html = '<div class=\"tp-cardlist\">';\n    rows.forEach(r=>{\n      const dow   = WD[r.dep.getDay()] || '';\n      const times = hhmm(r.dep) + ' <span class=\"tp-arrow\">\u2192<\/span> ' + hhmm(r.arr);\n      html += '<div class=\"tp-card\">'+boostersHtml(r, true)+\n        \/\/ Row 1: Date + weekday + times\n        '<div class=\"tp-mrow\">'+\n          '<div class=\"lhs\"><span class=\"tp-sub\">'+dShort(r.dep)+'<\/span><span class=\"tp-day\">'+dow+'<\/span><\/div>'+\n          '<div class=\"rhs\"><span class=\"tp-time\">'+times+'<\/span><\/div>'+\n        '<\/div>';\n\n      if (showShip) {\n        html +=\n        \/\/ Row 2: Ship\n        '<div class=\"tp-mrow\">'+\n          '<div class=\"lhs\">'+shipBadge(r.ship)+'<\/div>'+\n          '<div class=\"rhs\"><\/div>'+\n        '<\/div>';\n      }\n\n      html +=\n        \/\/ Row 3: Operator + route label\n        '<div class=\"tp-mrow\">'+\n          '<div class=\"lhs\">'+opCell(r)+'<\/div>'+\n          '<div class=\"rhs\"><span class=\"tp-route-ticket\">'+routeTicketHtml(routeLabel(r.routeId))+'<\/span><\/div>'+\n        '<\/div>'+\n      '<\/div>';\n    });\n    html += '<\/div>';\n    return html;\n  }\n\n  function renderExtendedCards(rows){\n    const ctaText = L.more_link || 'More sailings';\n    let html = '<div class=\"tp-cardlist\">';\n    rows.forEach(r=>{\n      const dow = WD[r.dep.getDay()] || '';\n      const link = r.opLink ? ('<a class=\"tp-ext-cta\" href=\"'+r.opLink+'\" target=\"_blank\" rel=\"nofollow noopener\">'+ctaText+' <span class=\"tp-ext-cta-arrow\">\u00bb<\/span><\/a>') : '<span class=\"tp-ext-cta\">'+ctaText+' <span class=\"tp-ext-cta-arrow\">\u00bb<\/span><\/span>';\n      html += '<div class=\"tp-ext-card\">'\n        + boostersHtml(r, true)\n        + '<div class=\"tp-ext-left\">'\n        +   '<div>'+opCell(r)+'<\/div>'\n        +   (showShip ? ('<div>'+shipBadge(r.ship)+'<\/div>') : '')\n        + '<\/div>'\n        + '<div class=\"tp-ext-mid\">'\n        +   '<div class=\"tp-ext-top\"><span class=\"tp-sub\">'+dShort(r.dep)+' <span class=\"tp-day\">'+dow+'<\/span><\/span><span class=\"tp-ext-dur\">'+dur(r.min)+'<\/span><\/div>'\n        +   '<div class=\"tp-ext-times\"><span class=\"tp-ext-time\">'+hhmm(r.dep)+'<\/span><span class=\"tp-ext-line\"><\/span><span class=\"tp-ext-dur\">'+dur(r.min)+'<\/span><span class=\"tp-ext-line\"><\/span><span class=\"tp-ext-time\">'+hhmm(r.arr)+'<\/span><\/div>'\n        +   '<div class=\"tp-ext-route\">'+routeLabel(r.routeId)+'<\/div>'\n        + '<\/div>'\n        + '<div class=\"tp-ext-right\">'+link+'<\/div>'\n        + '<\/div>';\n    });\n    html += '<\/div>';\n    return html;\n  }\n\n  \/\/ Safe fetch helper\n  async function fetchOne(routeId, from, to){\n    try{\n      const url = new URL(cfg.rest);\n      url.searchParams.set('route', String(routeId));\n      url.searchParams.set('from', from);\n      url.searchParams.set('to', to);\n      const res = await fetch(url.toString(), {credentials:'same-origin'});\n      if(!res.ok) return { rid: routeId, error: 'HTTP '+res.status };\n      const json = await res.json();\n      const list = (json && json.data && Array.isArray(json.data.rows)) ? json.data.rows : [];\n      return { rid: routeId, rows: list };\n    }catch(e){\n      return { rid: routeId, error: String(e && e.message ? e.message : e) };\n    }\n  }\n\n  async function load(){\n    btn.disabled = true; setLoader(true); status.textContent = L.status_loading;\n\n    const start = new Date(dateEl.value || new Date());\n    const days  = (daySetup === 'modern') ? 1 : Math.max(1, parseInt(daysEl.value,10)||1);\n    const end   = new Date(start); end.setDate(start.getDate()+days-1);\n    const fromIso = iso(start), toIso = iso(end);\n\n    try{\n      const results  = await Promise.all((cfg.routes||[]).map(rid=>fetchOne(rid, fromIso, toIso)));\n      const oks  = results.filter(r => !r.error);\n      const errs = results.filter(r =>  r.error);\n\n      const all = [];\n      oks.forEach(({rid, rows})=>{\n        rows.forEach(t=>{\n          all.push({\n            routeId: rid,\n            opId: t.operatorId || null,\n            opName: t.operatorName || '',\n            opLogo: t.operatorLogo || '',\n            opLink: t.operatorLink || '',\n            dep: toLocal(t.departureTime),\n            arr: toLocal(t.arrivalTime),\n            min: t.durationInMinutes || 0,\n            ship: t.shipName || ''\n          });\n        });\n      });\n\n      let rows = all;\n      if (Array.isArray(cfg.opFilter) && cfg.opFilter.length>0) {\n        rows = all.filter(r => r.opId && cfg.opFilter.includes(String(r.opId)));\n      }\n\n      rows.sort((a,b)=> a.dep - b.dep);\n\n      const todayStr = new Date().toDateString();\n      const nowMs = Date.now();\n      const arrivedToday = rows\n        .filter(r => (r.dep instanceof Date) && (r.arr instanceof Date) && r.dep.toDateString() === todayStr && r.arr.getTime() <= nowMs)\n        .sort((a,b) => b.arr - a.arr);\n      if (arrivedToday.length > 2) {\n        const keep = new Set(arrivedToday.slice(0,2).map(rowKey));\n        rows = rows.filter(r => {\n          const isArrivedToday = (r.dep instanceof Date) && (r.arr instanceof Date) && r.dep.toDateString() === todayStr && r.arr.getTime() <= nowMs;\n          return !isArrivedToday || keep.has(rowKey(r));\n        });\n      }\n\n      const total = rows.length;\n      if (total===0){\n        status.textContent = L.status_empty + (errs.length ? ' (some routes returned no data or errors)' : '');\n        clearStatusInline();\n        out.innerHTML='';\n        setLoader(false); btn.disabled=false; return;\n      }\n\n      const visibleRows = (limit10 && !revealAll && rows.length > 10) ? rows.slice(0,10) : rows;\n      const hiddenCount = rows.length - visibleRows.length;\n      soonKey = pickSoonKey(visibleRows);\n      featuredKey = pickFeaturedKey(visibleRows, soonKey);\n\n      status.textContent = errs.length ? ('Skipped '+errs.length+' route'+(errs.length>1?'s':'')) : '';\n      setStatusInline(\n  (L.status_found || '%d sailings found').replace('%d', '<strong>'+total+'<\/strong>')\n);\n      out.innerHTML = renderTable(visibleRows) + renderCards(visibleRows) + moreButtonHtml(hiddenCount);\n      bindRowLinks();\n      if (navHost) navHost.innerHTML = navHtml();\n\n    } catch(e){\n      status.textContent = 'Failed to load data';\n      out.innerHTML = '<pre>'+String(e.message||e)+'<\/pre>';\n    } finally {\n      setLoader(false);\n      btn.disabled = false;\n    }\n  }\n\n  wrap.addEventListener('click', function(e){\n    const nav = e.target.closest('.tp-day-nav a[data-shift]');\n    if (nav) {\n      e.preventDefault();\n      shiftDate(parseInt(nav.getAttribute('data-shift'),10) || 0);\n      return;\n    }\n    const more = e.target.closest('.tp-more-btn');\n    if (more) {\n      e.preventDefault();\n      revealAll = true;\n      load();\n    }\n  });\n\n  btn.addEventListener('click', load);\n  if (navHost) navHost.innerHTML = navHtml();\n  renderLocalTimes();\n  setInterval(renderLocalTimes, 30000);\n  if (cfg.autoload) load();\n})();\n<\/script>\n\n\t\t\t\t<h3>Dover naar Duinkerken<\/h3>\n\t\t\t\t<div class=\"tp-wrap tp-theme-extended_cards tp-day-setup-modern\" data-config=\"{&quot;rest&quot;:&quot;https:\\\/\\\/dover-dunkirk.com\\\/nl\\\/wp-json\\\/timetables-pro\\\/v1\\\/timetables&quot;,&quot;routes&quot;:[100],&quot;days&quot;:1,&quot;autoload&quot;:true,&quot;theme&quot;:&quot;extended_cards&quot;,&quot;daySetup&quot;:&quot;modern&quot;,&quot;limit10&quot;:false,&quot;routeLabels&quot;:{&quot;100&quot;:&quot;Dover-Duinkerken&quot;},&quot;opFilter&quot;:[&quot;6&quot;],&quot;labels&quot;:{&quot;ui_date&quot;:&quot;Datum&quot;,&quot;ui_days&quot;:&quot;Dagen&quot;,&quot;ui_button&quot;:&quot;Afvaarten tonen&quot;,&quot;status_idle&quot;:&quot;Kies een datum en klik op Afvaarten tonen&quot;,&quot;status_loading&quot;:&quot;Laden...&quot;,&quot;status_empty&quot;:&quot;Geen afvaarten gevonden&quot;,&quot;status_found&quot;:&quot;%d afvaarten gevonden&quot;,&quot;th_date&quot;:&quot;Datum&quot;,&quot;th_dep&quot;:&quot;Vertrek&quot;,&quot;th_arr&quot;:&quot;Aankomst&quot;,&quot;th_dur&quot;:&quot;Duur&quot;,&quot;th_ship&quot;:&quot;Schip&quot;,&quot;th_op&quot;:&quot;Operator&quot;,&quot;th_route&quot;:&quot;Route&quot;,&quot;wd_sun&quot;:&quot;ZO&quot;,&quot;wd_mon&quot;:&quot;MA&quot;,&quot;wd_tue&quot;:&quot;DI&quot;,&quot;wd_wed&quot;:&quot;WO&quot;,&quot;wd_thu&quot;:&quot;DO&quot;,&quot;wd_fri&quot;:&quot;VR&quot;,&quot;wd_sat&quot;:&quot;ZA&quot;,&quot;summary_footer_one&quot;:&quot;\\u00bb Bekijk alle %s afvaarten in onze dienstregeling&quot;,&quot;summary_footer_two&quot;:&quot;\\u00bb Bekijk meer %1$s en %2$s afvaarten in onze dienstregeling&quot;,&quot;summary_footer_generic&quot;:&quot;Bekijk onze dienstregeling voor meer afvaarten&quot;,&quot;summary_header&quot;:&quot;De volgende twee afvaarten:&quot;,&quot;summary_no_upcoming&quot;:&quot;Geen aankomende afvaarten gevonden&quot;,&quot;more_link&quot;:&quot;Meer afvaarten&quot;,&quot;more_departures_button&quot;:&quot;Meer afvaarten tonen&quot;,&quot;day_nav_previous&quot;:&quot;Vorige dag tonen&quot;,&quot;day_nav_next&quot;:&quot;Volgende dag tonen&quot;,&quot;day_nav_today&quot;:&quot;Vandaag tonen&quot;,&quot;day_nav_tomorrow&quot;:&quot;Morgen tonen&quot;,&quot;local_time_pair&quot;:&quot;Lokale tijd vertrekhaven: %1$s \\\/ Lokale tijd aankomsthaven: %2$s&quot;,&quot;local_time_combined&quot;:&quot;Lokale tijd vertrek- en aankomsthaven: %s&quot;,&quot;tag_often_booked&quot;:&quot;\\u2b50 Vaak geboekt&quot;,&quot;tag_leaving_soon&quot;:&quot;\\ud83d\\udd34 Vertrekt binnenkort&quot;,&quot;tag_currently_sailing&quot;:&quot;\\ud83d\\udfe2 Nu onderweg&quot;,&quot;tag_arrived&quot;:&quot;\\u26ab Aangekomen&quot;,&quot;tag_overnight&quot;:&quot;Nachtvaart&quot;},&quot;showLogo&quot;:true,&quot;activityBoosters&quot;:true,&quot;title&quot;:&quot;&quot;,&quot;shipMap&quot;:[],&quot;shipLinks&quot;:[],&quot;showShip&quot;:false,&quot;departurePort&quot;:&quot;Dover&quot;,&quot;arrivalPort&quot;:&quot;Dunkirk&quot;,&quot;departureTimezone&quot;:&quot;Europe\\\/London&quot;,&quot;arrivalTimezone&quot;:&quot;Europe\\\/Paris&quot;}\">\n  <div class=\"tp-controls\" role=\"group\" aria-label=\"Timetable controls\">\n    <div>\n      <label for=\"tp-date-ops\">Datum<\/label><br>\n      <input id=\"tp-date-ops\" class=\"tp-date\" type=\"date\" aria-label=\"Datum\">\n    <\/div>\n    <div class=\"tp-day-field\">\n      <label for=\"tp-range-ops\">Dagen<\/label><br>\n      <select id=\"tp-range-ops\" class=\"tp-range\" aria-label=\"Dagen\">\n        <option value=\"1\">1<\/option><option value=\"3\">3<\/option><option value=\"7\">7<\/option><option value=\"14\">14<\/option>\n      <\/select>\n    <\/div>\n    <div><button id=\"tp-load-ops\" class=\"tp-btn\">Afvaarten tonen<\/button><\/div>\n  <\/div>\n\n  <div class=\"tp-local-nav-row\">\n    <div class=\"tp-local-times\" id=\"tp-local-times-ops\" aria-live=\"polite\"><\/div>\n    <div class=\"tp-day-nav-host\"><\/div>\n  <\/div>\n\n  \n  <div id=\"tp-status-ops\" class=\"tp-muted\" aria-live=\"polite\">Kies een datum en klik op Afvaarten tonen<\/div>\n\n  <div id=\"tp-ops-results\"><\/div>\n\n  <div class=\"tp-loader\" aria-hidden=\"true\">\n    <div class=\"tp-loader-card\">\n      <div class=\"tp-spinner\" aria-hidden=\"true\"><\/div>\n      <div class=\"tp-loader-text\">Laden...<\/div>\n    <\/div>\n  <\/div>\n<\/div>\n\n<script>\n(function(){\n  const wrap   = document.currentScript.previousElementSibling;\n  const cfg    = JSON.parse(wrap.getAttribute('data-config')||'{}');\n  const L      = cfg.labels||{};\n  const dateEl = wrap.querySelector('#tp-date-ops');\n  const daysEl = wrap.querySelector('#tp-range-ops');\n  const btn    = wrap.querySelector('#tp-load-ops');\n  const status = wrap.querySelector('#tp-status-ops');\n  const out    = wrap.querySelector('#tp-ops-results');\n  const loader = wrap.querySelector('.tp-loader');\n  const navHost = wrap.querySelector('.tp-day-nav-host');\n  const localTimesEl = wrap.querySelector('#tp-local-times-ops');\n\n  const showShip = (cfg.showShip !== false && cfg.showShip !== 0 && cfg.showShip !== '0');\n  const activityBoosters = !!cfg.activityBoosters;\n  const daySetup = (cfg.daySetup === 'modern') ? 'modern' : 'classic';\n  const limit10 = !!cfg.limit10;\n  let featuredKey = '';\n  let soonKey = '';\n  let revealAll = false;\n\n  if (daySetup === 'modern') {\n    const dayField = wrap.querySelector('.tp-day-field');\n    if (dayField) dayField.style.display = 'none';\n  }\n\n  dateEl.valueAsDate = new Date();\n  dateEl.min = new Date().toISOString().split('T')[0];\n  Array.from(daysEl.options).forEach(o=>{ if(parseInt(o.value,10)===parseInt(cfg.days||7,10)) o.selected=true; });\n\n  function pad(n){ return String(n).padStart(2,'0'); }\n  function iso(d){ return d.getFullYear()+'-'+pad(d.getMonth()+1)+'-'+pad(d.getDate()); }\n  function toLocal(s){ return new Date(s); }\n  function hhmm(d){ return d.toLocaleTimeString([], {hour:'2-digit', minute:'2-digit'}); }\n  function dShort(d){ return d.toLocaleDateString([], {day:'numeric', month:'short'}); }\n  function dur(m){ const h=Math.floor(m\/60), r=m%60; return r? (h+'h '+r+'m') : (h+'h'); }\n\n  const WD = [\n    L.wd_sun || 'SUN',\n    L.wd_mon || 'MON',\n    L.wd_tue || 'TUE',\n    L.wd_wed || 'WED',\n    L.wd_thu || 'THU',\n    L.wd_fri || 'FRI',\n    L.wd_sat || 'SAT'\n  ];\n\n  function setLoader(v){ loader.classList.toggle('show', !!v); loader.setAttribute('aria-hidden', v?'false':'true'); }\n\n  function formatZoneTime(tz){\n    if (!tz) return '--:--';\n    try {\n      return new Intl.DateTimeFormat([], {hour:'2-digit', minute:'2-digit', hour12:false, timeZone: tz}).format(new Date());\n    } catch (e) {\n      return '--:--';\n    }\n  }\n\n  function renderLocalTimes(){\n    if (!localTimesEl) return;\n    if (!cfg.departureTimezone || !cfg.arrivalTimezone) {\n      localTimesEl.textContent = '';\n      return;\n    }\n    const depTime = formatZoneTime(cfg.departureTimezone);\n    const arrTime = formatZoneTime(cfg.arrivalTimezone);\n    const pairTpl = L.local_time_pair || 'Departure Port Local Time: %1$s \/ Arrival Port Local Time: %2$s';\n    const combinedTpl = L.local_time_combined || 'Departure & Arrival Port Local Time: %s';\n    if (depTime === arrTime) {\n      localTimesEl.textContent = combinedTpl.replace('%s', depTime);\n      return;\n    }\n    localTimesEl.textContent = pairTpl.replace('%1$s', depTime).replace('%2$s', arrTime);\n  }\n\n  function setStatusInline(html){\n    let box = wrap.querySelector('.tp-controls-status');\n    if (!box) {\n      box = document.createElement('div');\n      box.className = 'tp-controls-status';\n      wrap.querySelector('.tp-controls').appendChild(box);\n    }\n    box.innerHTML = html || '';\n  }\n\n  function clearStatusInline(){\n    const box = wrap.querySelector('.tp-controls-status');\n    if (box) box.innerHTML = '';\n  }\n\n  function navHtml(){\n    if (daySetup !== 'modern') return '';\n    const base = new Date(dateEl.value || new Date());\n    const today = new Date();\n    const tomorrow = new Date(today);\n    tomorrow.setDate(today.getDate() + 1);\n    const isToday = base.toDateString() === today.toDateString();\nlet prevLabel = L.day_nav_previous || 'Show previous day';\nlet nextLabel = L.day_nav_next || 'Show next day';\nif (isToday) nextLabel = L.day_nav_tomorrow || 'Show tomorrow';\nif (base.toDateString() === tomorrow.toDateString()) prevLabel = L.day_nav_today || 'Show today';\n    return '<div class=\"tp-day-nav\">'\n      + (isToday ? '' : '<a href=\"#\" data-shift=\"-1\">'+prevLabel+'<\/a>')\n      + '<a href=\"#\" data-shift=\"1\">'+nextLabel+'<\/a>'\n      + '<\/div>';\n  }\n\n  function shiftDate(delta){\n    const base = new Date(dateEl.value || new Date());\n    base.setDate(base.getDate() + delta);\n    dateEl.value = iso(base);\n    load();\n  }\n\n  function moreButtonHtml(hiddenCount){\n    if (!limit10 || revealAll || hiddenCount <= 0) return '';\n    return '<div style=\"margin-top:12px;text-align:center\">'\n      + '<button type=\"button\" class=\"tp-btn tp-more-btn\">'+(L.more_departures_button || 'Show more departures')+' ('+hiddenCount+')<\/button>'\n      + '<\/div>';\n  }\n\n  function opCell(r){\n    const name = r.opName || ('Operator '+(r.opId||''));\n    const logo = (cfg.showLogo && r.opLogo) ? '<img decoding=\"async\" src=\"'+r.opLogo+'\" alt=\"'+name+'\"> ' : '';\n    const label = logo + '<span>'+name+'<\/span>';\n    return r.opLink ? '<a class=\"tp-op\" href=\"'+r.opLink+'\" target=\"_blank\" rel=\"nofollow noopener\">'+label+'<\/a>' : '<span class=\"tp-op\">'+label+'<\/span>';\n  }\n\n  function shipInfo(original){\n    const key = (original||'').toLowerCase().trim();\n    const label = (cfg.shipMap && cfg.shipMap[key]) || original || '';\n    const href  = (cfg.shipLinks && cfg.shipLinks[key]) || '';\n    return {label, href};\n  }\n\n  function shipBadge(original){\n    const s = shipInfo(original);\n    const badge = '<span class=\"tp-badge\">'+(s.label||'')+'<\/span>';\n    return s.href ? ('<a href=\"'+s.href+'\" target=\"_blank\" rel=\"nofollow noopener\">'+badge+'<\/a>') : badge;\n  }\n\n  function rowKey(r){\n    return [String(r.routeId||''), String(r.opId||''), String(+r.dep||0), String(+r.arr||0)].join('|');\n  }\n\n  function pickFeaturedKey(rows, avoidKey){\n    if (!activityBoosters || !rows.length) return '';\n    const routesSum = Array.isArray(cfg.routes) ? cfg.routes.reduce((acc, n)=>acc + (parseInt(n,10)||0), 0) : 0;\n    const dateSeed = parseInt(String(dateEl.value || '').replace(\/-\/g,''), 10) || 0;\n\n    let pool = rows;\n    if (avoidKey) {\n      const soonIdx = rows.findIndex(r => rowKey(r) === avoidKey);\n      if (soonIdx >= 0) {\n        const later = rows.slice(soonIdx + 1).filter(r => rowKey(r) !== avoidKey);\n        pool = later.length ? later : rows.filter(r => rowKey(r) !== avoidKey);\n      } else {\n        pool = rows.filter(r => rowKey(r) !== avoidKey);\n      }\n    }\n\n    if (!pool.length) return '';\n    const idx = Math.abs((routesSum + dateSeed + rows.length) % pool.length);\n    return rowKey(pool[idx]);\n  }\n\n  function pickSoonKey(rows){\n    if (!activityBoosters || !rows.length) return '';\n    const now = Date.now();\n    const todayStr = new Date(now).toDateString();\n    const firstUpcoming = rows.find(r => (r.dep instanceof Date) && r.dep.getTime() > now && r.dep.toDateString() === todayStr);\n    return firstUpcoming ? rowKey(firstUpcoming) : '';\n  }\n\n  function boostersFor(r){\n    if (!activityBoosters) return [];\n    const now = Date.now();\n    const depMs = (r.dep instanceof Date) ? r.dep.getTime() : 0;\n    const arrMs = (r.arr instanceof Date) ? r.arr.getTime() : 0;\n    const depIsToday = (r.dep instanceof Date) && (new Date(now).toDateString() === r.dep.toDateString());\n\n    if (depMs > 0 && arrMs > 0 && depMs <= now && arrMs > now) {\n      return [{cls:'tp-booster-sailing', text:(L.tag_currently_sailing || '\ud83d\udfe2 Currently sailing')}];\n    }\n    if (depIsToday && arrMs > 0 && arrMs <= now) {\n      return [{cls:'tp-booster-arrived', text:(L.tag_arrived || '\u26ab Arrived')}];\n    }\n    if (rowKey(r) === soonKey) return [{cls:'tp-booster-soon', text:(L.tag_leaving_soon || '\ud83d\udd34 Leaving soon')}];\n    if (r.dep && r.arr && r.dep.toDateString() !== r.arr.toDateString()) return [{cls:'tp-booster-overnight', text:(L.tag_overnight || 'Overnight')}];\n\n    return [];\n  }\n\n  function boostersHtml(r, floating){\n    const tags = boostersFor(r);\n    if (!tags.length) return '';\n    const cls = floating ? 'tp-boosters tp-boosters-float' : 'tp-boosters';\n    return '<div class=\"'+cls+'\">' + tags.map(t => '<span class=\"tp-booster '+t.cls+'\">'+boosterLabelHtml(t.text)+'<\/span>').join('') + '<\/div>';\n  }\n\n  function boosterLabelHtml(text){\n    return String(text || '').replace(\/^(\ud83d\udd34|\ud83d\udfe2|\u26ab|\u2b50)\\s*\/, '<span class=\"tp-booster-emoji\">$1<\/span>');\n  }\n\n  function routeTicketHtml(label){\n    const raw = String(label || '').trim();\n    if (!raw) return '';\n    if (cfg.theme !== 'small_cards') return escAttr(raw);\n    const parts = raw.split(\/\\s*[\\-\u2013]\\s*\/, 2);\n    if (parts.length < 2) return escAttr(raw);\n    return escAttr(parts[0]) + '<br>' + escAttr(parts[1]);\n  }\n\n  function escAttr(v){\n    return String(v||'').replace(\/[&<>\"']\/g, m => ({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'}[m]));\n  }\n\n  function bindRowLinks(){\n    if (cfg.theme !== 'max_clickouts') return;\n    out.querySelectorAll('tr.tp-row-link').forEach((row)=>{\n      row.setAttribute('role','link');\n      row.setAttribute('tabindex','0');\n      row.addEventListener('click', (e)=>{\n        if (e.target && e.target.closest('a')) return;\n        const href = row.getAttribute('data-row-link');\n        if (!href) return;\n        window.open(href, '_blank', 'noopener,noreferrer');\n      });\n      row.addEventListener('keydown', (e)=>{\n        if (e.key !== 'Enter' && e.key !== ' ') return;\n        e.preventDefault();\n        row.click();\n      });\n    });\n  }\n\n  function routeLabel(rid){\n    return (cfg.routeLabels && (cfg.routeLabels[String(rid)] || cfg.routeLabels[rid])) || String(rid);\n  }\n\n  function renderTable(rows){\n    const th = {date:L.th_date,dep:L.th_dep,arr:L.th_arr,dur:L.th_dur,ship:L.th_ship,route:L.th_route,op:L.th_op};\n\n    const headCells = [\n      '<th>'+th.date+'<\/th>',\n      '<th>'+th.dep+'<\/th>',\n      '<th>'+th.arr+'<\/th>',\n      '<th>'+th.dur+'<\/th>'\n    ];\n    if (showShip) {\n      headCells.push('<th>'+th.ship+'<\/th>');\n    }\n    headCells.push('<th>'+th.route+'<\/th>');\n    headCells.push('<th>'+th.op+'<\/th>');\n\n    let html = '<table class=\"tp-table\"><thead><tr>'+headCells.join('')+'<\/tr><\/thead><tbody>';\n    rows.forEach(r=>{\n      const dow = WD[r.dep.getDay()] || '';\n      const clickable = (cfg.theme === 'max_clickouts' && r.opLink);\n      const rowAttr = clickable ? (' class=\"tp-row-link\" data-row-link=\"'+escAttr(r.opLink)+'\"') : '';\n      const dateBoosters = (cfg.theme === 'max_clickouts') ? '' : boostersHtml(r, false);\n      const routeBoosters = (cfg.theme === 'max_clickouts') ? boostersHtml(r, false) : '';\n      const cells = [\n        '<td>'+dShort(r.dep)+' <span class=\"tp-day\">'+dow+'<\/span>'+dateBoosters+'<\/td>',\n        '<td>'+hhmm(r.dep)+'<\/td>',\n        '<td>'+hhmm(r.arr)+'<\/td>',\n        '<td>'+dur(r.min)+'<\/td>'\n      ];\n      if (showShip) {\n        cells.push('<td>'+shipBadge(r.ship)+'<\/td>');\n      }\n      cells.push('<td>'+routeBoosters+'<div>'+routeLabel(r.routeId)+'<\/div><\/td>');\n      cells.push('<td>'+opCell(r)+'<\/td>');\n      html += '<tr'+rowAttr+'>'+cells.join('')+'<\/tr>';\n    });\n    html += '<\/tbody><\/table>';\n    return html;\n  }\n\n  function renderCards(rows){\n    if (cfg.theme === 'extended_cards') {\n      return renderExtendedCards(rows);\n    }\n\n    let html = '<div class=\"tp-cardlist\">';\n    rows.forEach(r=>{\n      const dow   = WD[r.dep.getDay()] || '';\n      const times = hhmm(r.dep) + ' <span class=\"tp-arrow\">\u2192<\/span> ' + hhmm(r.arr);\n      html += '<div class=\"tp-card\">'+boostersHtml(r, true)+\n        \/\/ Row 1: Date + weekday + times\n        '<div class=\"tp-mrow\">'+\n          '<div class=\"lhs\"><span class=\"tp-sub\">'+dShort(r.dep)+'<\/span><span class=\"tp-day\">'+dow+'<\/span><\/div>'+\n          '<div class=\"rhs\"><span class=\"tp-time\">'+times+'<\/span><\/div>'+\n        '<\/div>';\n\n      if (showShip) {\n        html +=\n        \/\/ Row 2: Ship\n        '<div class=\"tp-mrow\">'+\n          '<div class=\"lhs\">'+shipBadge(r.ship)+'<\/div>'+\n          '<div class=\"rhs\"><\/div>'+\n        '<\/div>';\n      }\n\n      html +=\n        \/\/ Row 3: Operator + route label\n        '<div class=\"tp-mrow\">'+\n          '<div class=\"lhs\">'+opCell(r)+'<\/div>'+\n          '<div class=\"rhs\"><span class=\"tp-route-ticket\">'+routeTicketHtml(routeLabel(r.routeId))+'<\/span><\/div>'+\n        '<\/div>'+\n      '<\/div>';\n    });\n    html += '<\/div>';\n    return html;\n  }\n\n  function renderExtendedCards(rows){\n    const ctaText = L.more_link || 'More sailings';\n    let html = '<div class=\"tp-cardlist\">';\n    rows.forEach(r=>{\n      const dow = WD[r.dep.getDay()] || '';\n      const link = r.opLink ? ('<a class=\"tp-ext-cta\" href=\"'+r.opLink+'\" target=\"_blank\" rel=\"nofollow noopener\">'+ctaText+' <span class=\"tp-ext-cta-arrow\">\u00bb<\/span><\/a>') : '<span class=\"tp-ext-cta\">'+ctaText+' <span class=\"tp-ext-cta-arrow\">\u00bb<\/span><\/span>';\n      html += '<div class=\"tp-ext-card\">'\n        + boostersHtml(r, true)\n        + '<div class=\"tp-ext-left\">'\n        +   '<div>'+opCell(r)+'<\/div>'\n        +   (showShip ? ('<div>'+shipBadge(r.ship)+'<\/div>') : '')\n        + '<\/div>'\n        + '<div class=\"tp-ext-mid\">'\n        +   '<div class=\"tp-ext-top\"><span class=\"tp-sub\">'+dShort(r.dep)+' <span class=\"tp-day\">'+dow+'<\/span><\/span><span class=\"tp-ext-dur\">'+dur(r.min)+'<\/span><\/div>'\n        +   '<div class=\"tp-ext-times\"><span class=\"tp-ext-time\">'+hhmm(r.dep)+'<\/span><span class=\"tp-ext-line\"><\/span><span class=\"tp-ext-dur\">'+dur(r.min)+'<\/span><span class=\"tp-ext-line\"><\/span><span class=\"tp-ext-time\">'+hhmm(r.arr)+'<\/span><\/div>'\n        +   '<div class=\"tp-ext-route\">'+routeLabel(r.routeId)+'<\/div>'\n        + '<\/div>'\n        + '<div class=\"tp-ext-right\">'+link+'<\/div>'\n        + '<\/div>';\n    });\n    html += '<\/div>';\n    return html;\n  }\n\n  \/\/ Safe fetch helper\n  async function fetchOne(routeId, from, to){\n    try{\n      const url = new URL(cfg.rest);\n      url.searchParams.set('route', String(routeId));\n      url.searchParams.set('from', from);\n      url.searchParams.set('to', to);\n      const res = await fetch(url.toString(), {credentials:'same-origin'});\n      if(!res.ok) return { rid: routeId, error: 'HTTP '+res.status };\n      const json = await res.json();\n      const list = (json && json.data && Array.isArray(json.data.rows)) ? json.data.rows : [];\n      return { rid: routeId, rows: list };\n    }catch(e){\n      return { rid: routeId, error: String(e && e.message ? e.message : e) };\n    }\n  }\n\n  async function load(){\n    btn.disabled = true; setLoader(true); status.textContent = L.status_loading;\n\n    const start = new Date(dateEl.value || new Date());\n    const days  = (daySetup === 'modern') ? 1 : Math.max(1, parseInt(daysEl.value,10)||1);\n    const end   = new Date(start); end.setDate(start.getDate()+days-1);\n    const fromIso = iso(start), toIso = iso(end);\n\n    try{\n      const results  = await Promise.all((cfg.routes||[]).map(rid=>fetchOne(rid, fromIso, toIso)));\n      const oks  = results.filter(r => !r.error);\n      const errs = results.filter(r =>  r.error);\n\n      const all = [];\n      oks.forEach(({rid, rows})=>{\n        rows.forEach(t=>{\n          all.push({\n            routeId: rid,\n            opId: t.operatorId || null,\n            opName: t.operatorName || '',\n            opLogo: t.operatorLogo || '',\n            opLink: t.operatorLink || '',\n            dep: toLocal(t.departureTime),\n            arr: toLocal(t.arrivalTime),\n            min: t.durationInMinutes || 0,\n            ship: t.shipName || ''\n          });\n        });\n      });\n\n      let rows = all;\n      if (Array.isArray(cfg.opFilter) && cfg.opFilter.length>0) {\n        rows = all.filter(r => r.opId && cfg.opFilter.includes(String(r.opId)));\n      }\n\n      rows.sort((a,b)=> a.dep - b.dep);\n\n      const todayStr = new Date().toDateString();\n      const nowMs = Date.now();\n      const arrivedToday = rows\n        .filter(r => (r.dep instanceof Date) && (r.arr instanceof Date) && r.dep.toDateString() === todayStr && r.arr.getTime() <= nowMs)\n        .sort((a,b) => b.arr - a.arr);\n      if (arrivedToday.length > 2) {\n        const keep = new Set(arrivedToday.slice(0,2).map(rowKey));\n        rows = rows.filter(r => {\n          const isArrivedToday = (r.dep instanceof Date) && (r.arr instanceof Date) && r.dep.toDateString() === todayStr && r.arr.getTime() <= nowMs;\n          return !isArrivedToday || keep.has(rowKey(r));\n        });\n      }\n\n      const total = rows.length;\n      if (total===0){\n        status.textContent = L.status_empty + (errs.length ? ' (some routes returned no data or errors)' : '');\n        clearStatusInline();\n        out.innerHTML='';\n        setLoader(false); btn.disabled=false; return;\n      }\n\n      const visibleRows = (limit10 && !revealAll && rows.length > 10) ? rows.slice(0,10) : rows;\n      const hiddenCount = rows.length - visibleRows.length;\n      soonKey = pickSoonKey(visibleRows);\n      featuredKey = pickFeaturedKey(visibleRows, soonKey);\n\n      status.textContent = errs.length ? ('Skipped '+errs.length+' route'+(errs.length>1?'s':'')) : '';\n      setStatusInline(\n  (L.status_found || '%d sailings found').replace('%d', '<strong>'+total+'<\/strong>')\n);\n      out.innerHTML = renderTable(visibleRows) + renderCards(visibleRows) + moreButtonHtml(hiddenCount);\n      bindRowLinks();\n      if (navHost) navHost.innerHTML = navHtml();\n\n    } catch(e){\n      status.textContent = 'Failed to load data';\n      out.innerHTML = '<pre>'+String(e.message||e)+'<\/pre>';\n    } finally {\n      setLoader(false);\n      btn.disabled = false;\n    }\n  }\n\n  wrap.addEventListener('click', function(e){\n    const nav = e.target.closest('.tp-day-nav a[data-shift]');\n    if (nav) {\n      e.preventDefault();\n      shiftDate(parseInt(nav.getAttribute('data-shift'),10) || 0);\n      return;\n    }\n    const more = e.target.closest('.tp-more-btn');\n    if (more) {\n      e.preventDefault();\n      revealAll = true;\n      load();\n    }\n  });\n\n  btn.addEventListener('click', load);\n  if (navHost) navHost.innerHTML = navHtml();\n  renderLocalTimes();\n  setInterval(renderLocalTimes, 30000);\n  if (cfg.autoload) load();\n})();\n<\/script>\n\n\t\t\t<\/section>\n\n\t\t\t<section id=\"duur\">\n\t\t\t\t<h2>Hoe lang duurt de overtocht Duinkerken naar Dover?<\/h2>\n\t\t\t\t<p>De overtocht duurt in beide richtingen 2 uur, wat je ticket ook zegt. Omdat Engeland een uur achterloopt op Frankrijk, staat op je ticket naar Dover een aankomsttijd die maar \u00e9\u00e9n uur na vertrek ligt. Terug naar Duinkerken lijkt het drie uur. Op de klok aan boord verandert er niets: je zet je horloge pas bij aankomst een uur terug, en op de terugweg een uur vooruit.<\/p>\n\t\t\t\t<div class=\"dd-panel dd-tw\"><table class=\"dd-table\">\n\t\t\t\t\t<thead><tr><th>Richting<\/th><th>Vertrek (lokaal)<\/th><th>Aankomst (lokaal)<\/th><th>Echte duur<\/th><\/tr><\/thead>\n\t\t\t\t\t<tbody>\n\t\t\t\t\t\t<tr><td>Duinkerken naar Dover<\/td><td class=\"dd-num\">14:00 (CEST)<\/td><td class=\"dd-num\">15:00 (BST)<\/td><td class=\"dd-num\">2 uur<\/td><\/tr>\n\t\t\t\t\t\t<tr><td>Dover naar Duinkerken<\/td><td class=\"dd-num\">12:00 (BST)<\/td><td class=\"dd-num\">15:00 (CEST)<\/td><td class=\"dd-num\">2 uur<\/td><\/tr>\n\t\t\t\t\t<\/tbody>\n\t\t\t\t<\/table><\/div>\n\t\t\t\t<p>Reken van loket tot A20 op drie tot drie\u00ebnhalf uur: een uur in de haven v\u00f3\u00f3r vertrek, twee uur varen en een kwartier tot een half uur voor het afrijden.<\/p>\n\t\t\t\t\t\t\t<div class=\"dd-figs\"><figure class=\"dd-figure\"><img loading=\"lazy\" src=\"https:\/\/dover-dunkirk.com\/nl\/wp-content\/uploads\/sites\/3\/2026\/09\/wake-leaving-dunkirk.webp\" alt=\"Kielzog van de veerboot bij vertrek uit de haven van Duinkerken\" width=\"1800\" height=\"1350\" loading=\"lazy\" decoding=\"async\"><figcaption>Vertrek uit Duinkerken: binnen een kwartier ligt de haven achter je.<\/figcaption><\/figure><figure class=\"dd-figure\"><img loading=\"lazy\" src=\"https:\/\/dover-dunkirk.com\/nl\/wp-content\/uploads\/sites\/3\/2026\/09\/entering-dover-harbour.webp\" alt=\"De veerboot vaart tussen de havenhoofden van Dover\" width=\"1800\" height=\"1350\" loading=\"lazy\" decoding=\"async\"><figcaption>Twee uur later: tussen de havenhoofden van Dover door.<\/figcaption><\/figure><\/div>\t\t\t<\/section>\n\n\t\t\t<section id=\"inchecken\">\n\t\t\t\t<h2>Wanneer sluit het inchecken?<\/h2>\n\t\t\t\t<p>Het inchecken sluit 60 minuten voor vertrek. Reken in Duinkerken op 75 tot 90 minuten van tevoren; in de schoolvakanties en op vrijdag en zaterdag op 90 tot 120 minuten. In <a href=\"https:\/\/dover-dunkirk.com\/nl\/haven-dover\/\">Dover<\/a> volgt na het incheckloket nog de Franse paspoortcontrole; reken daar buiten de vakanties op 60 tot 90 minuten, in de schoolvakanties op 90 tot 120 minuten. Wat er gebeurt als je te laat bent, hangt af van je tickettype (<a href=\"https:\/\/dover-dunkirk.com\/nl\/prijzen-duinkerken-dover\/#tickettypes\">Economy of Flexi<\/a>); kijk in de voorwaarden van je boeking.<\/p>\n\t\t\t\t<ol class=\"dd-steps\">\n\t\t\t\t\t<li><b>Terminal Loon-Plage, niet het centrum van Duinkerken<\/b><span>Zet je navigatie op Loon-Plage of Port 5625 (alles over de <a href=\"https:\/\/dover-dunkirk.com\/nl\/haven-duinkerken\/\">haven Duinkerken<\/a>). Vanaf de A16 neem je afslag 53 en volg je de borden Car Ferry; de hele <a href=\"https:\/\/dover-dunkirk.com\/nl\/route-naar-duinkerken\/\">route naar Duinkerken<\/a> staat op een aparte pagina.<\/span><\/li>\n\t\t\t\t\t<li><b>Inchecken bij de loketten<\/b><span>Je toont je boekingsnummer of de e-mail. Je krijgt een spiegelhanger met je rijstrook en de afvaarttijd.<\/span><\/li>\n\t\t\t\t\t<li><b>Grens- en douanecontrole<\/b><span>Paspoortcontrole van Frankrijk en het Verenigd Koninkrijk, daarna eventueel een douanecheck. Houd paspoorten en kentekenbewijs bij de hand.<\/span><\/li>\n\t\t\t\t\t<li><b>Wachten in je rijstrook<\/b><span>Je rijdt door naar de rijstrook op je hanger. Het inschepen begint ongeveer 30 minuten voor vertrek.<\/span><\/li>\n\t\t\t\t<\/ol>\n\t\t\t\t<a class=\"dd-linkrow\" href=\"https:\/\/dover-dunkirk.com\/nl\/inchecken\/\">Inchecken stap voor stap, met foto&#8217;s <svg class=\"dd-ic\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M5 12h14M13 6l6 6-6 6\"\/><\/svg><\/a>\n\t\t\t\t<div class=\"dd-tip\"><svg class=\"dd-ic\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"9\"\/><path d=\"M12 11v5M12 8h.01\"\/><\/svg><span>Huisdieren blijven tijdens de overtocht in de auto (zie <a href=\"https:\/\/dover-dunkirk.com\/nl\/aan-boord\/\">aan boord en huisdieren<\/a>). Laat je hond uit v\u00f3\u00f3r het inchecken; naast het terminalgebouw is een uitlaatplek.<\/span><\/div>\n\t\t\t<\/section>\n\n\t\t\t<section id=\"nacht\">\n\t\t\t\t<h2>Nachtafvaarten en weekend<\/h2>\n\t\t\t\t<p>De afvaart van 23:59 uit Duinkerken en die van 04:00 zijn er niet elke dag; in het weekend vervallen enkele afvaarten. Het overzicht hierboven laat per dag zien wat er vaart. Boek een nachtafvaart alleen als je hem in het schema ziet staan, en houd er rekening mee dat de terminal &#8217;s nachts beperkte voorzieningen heeft.<\/p>\n\t\t\t\t<div class=\"dd-tip\"><svg class=\"dd-ic\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"9\"\/><path d=\"M12 11v5M12 8h.01\"\/><\/svg><span><strong>Ons advies.<\/strong> De afvaarten van 04:00 en 06:00 zijn op de prijzenpagina vaak de goedkoopste van de dag, maar vanuit Utrecht of Antwerpen betekent 04:00 vertrekken om middernacht. Een overnachting in Duinkerken of Loon-Plage, 5 tot 20 minuten van de terminal, maakt zo&#8217;n afvaart bruikbaar en haalt de nachtrit eruit. <a href=\"https:\/\/dover-dunkirk.com\/nl\/go\/stay22-dunkirk\/\" rel=\"sponsored nofollow noopener\" target=\"_blank\">Bekijk hotels in Duinkerken voor de nacht v\u00f3\u00f3r je afvaart<\/a>.<\/span><\/div>\n\t\t\t<\/section>\n\n\t\t\t<section id=\"vragen\">\n\t\t\t\t<h2>Veelgestelde vragen over de vaartijden<\/h2>\n\t\t\t\t<div class=\"dd-faq\">\n\t\t\t\t\t<details open><summary>Hoe vaak vaart de veerboot van Duinkerken naar Dover? <svg class=\"dd-ic\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M6 9l6 6 6-6\"\/><\/svg><\/summary><p>Tot elf keer per dag, op weekdagen meestal tien: om 04:00, 06:00, 08:00, 10:00, 12:00, 14:00, 16:00, 18:00, 20:00 en 23:59. In het weekend vervallen enkele afvaarten.<\/p><\/details>\n\t\t\t\t\t<details open><summary>Zijn de tijden in Nederlandse tijd? <svg class=\"dd-ic\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M6 9l6 6 6-6\"\/><\/svg><\/summary><p>De vertrektijden uit Duinkerken staan in Franse tijd, die gelijk is aan de Nederlandse en Belgische tijd. De vertrektijden uit Dover staan in Engelse tijd, een uur eerder.<\/p><\/details>\n\t\t\t\t\t<details open><summary>Hoe laat is de eerste en de laatste afvaart? <svg class=\"dd-ic\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M6 9l6 6 6-6\"\/><\/svg><\/summary><p>De eerste afvaart uit Duinkerken is om 04:00, de laatste om 23:59 op dagen dat die vaart. Uit Dover vaart de eerste om 02:00 en de laatste om 22:00 Engelse tijd.<\/p><\/details>\n\t\t\t\t\t<details open><summary>Wat gebeurt er bij vertraging of annulering? <svg class=\"dd-ic\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M6 9l6 6 6-6\"\/><\/svg><\/summary><p>Bij <a href=\"https:\/\/dover-dunkirk.com\/nl\/weer\/\">storm<\/a> of een technisch probleem vaart DFDS soms met minder schepen; sommige afvaarten vervallen dan of worden samengevoegd. Je boeking geldt dan voor de eerstvolgende afvaart met plek. DFDS stuurt een e-mail of sms naar de gegevens uit je boeking; controleer bij een boeking via DirectFerries dat je eigen contactgegevens erin staan. Bij een vertraging van meer dan 90 minuten mag je kiezen tussen omboeken en terugbetaling (Verordening 1177\/2010). Meldingen van vandaag en je rechten staan op de pagina <a href=\"https:\/\/dover-dunkirk.com\/nl\/vaarupdates\/\">vaarupdates<\/a>.<\/p><\/details>\n\t\t\t\t<\/div>\n\t\t\t<\/section>\n\t\t<\/div>\n\n\t\t<aside class=\"dd-aside\">\n\t\t\t<div class=\"dd-panel\"><h3>Boeken voor een afvaart<\/h3><p class=\"dd-small dd-muted\" style=\"margin:0 0 12px\">Prijzen verschillen per afvaart en per dag. Vergelijk ze voor je gekozen tijd.<\/p><a class=\"dd-btn\" href=\"https:\/\/dover-dunkirk.com\/nl\/go\/directferries-dunkirk-dover\/\" target=\"_blank\" rel=\"sponsored nofollow noopener\">Prijzen vergelijken<\/a><p class=\"dd-disc\">Je boekt via onze partner DirectFerries.<\/p><\/div>\n\t\t\t<div class=\"dd-panel\"><h3>De route in cijfers<\/h3><div class=\"dd-panel dd-facts\"><dl><div><dt>Overtocht<\/dt><dd class=\"dd-num\">2 uur<\/dd><\/div><div><dt>Afvaarten per dag<\/dt><dd class=\"dd-num\">tot 11 per richting<\/dd><\/div><div><dt>Check-in sluit<\/dt><dd class=\"dd-num\">60 min voor vertrek<\/dd><\/div><div><dt>Auto + 5, enkele reis<\/dt><dd class=\"dd-num\">vanaf \u20ac 114<\/dd><\/div><div><dt>Voetpassagiers<\/dt><dd class=\"dd-num\">niet toegestaan<\/dd><\/div><div><dt>Huisdieren<\/dt><dd class=\"dd-num\">blijven in de auto<\/dd><\/div><\/dl><\/div><\/div>\n\t\t\t<div class=\"dd-panel\"><h3>Op deze pagina<\/h3><nav class=\"dd-toc\"><a href=\"#vandaag\">Afvaarten vandaag<\/a><a href=\"#week\">Komende week naar Dover<\/a><a href=\"#week-terug\">Komende week naar Duinkerken<\/a><a href=\"#datum\">Andere datum<\/a><a href=\"#duur\">Duur van de overtocht<\/a><a href=\"#inchecken\">Inchecken<\/a><a href=\"#nacht\">Nacht en weekend<\/a><a href=\"#vragen\">Vragen<\/a><\/nav><\/div>\n\t\t<\/aside>\n\t<\/div>\n<\/div>\n\n","protected":false},"excerpt":{"rendered":"<p>Vaartijden Duinkerken naar Dover DFDS vaart overdag ongeveer elke twee uur, met enkele nacht- en vroege-ochtendafvaarten, in beide richtingen. Hieronder staan de afvaarten van vandaag, het overzicht voor de komende week en de tijden waarop het inchecken sluit. Vertrektijden zijn in de lokale tijd van de vertrekhaven. Bron: dienstregeling DFDS via DirectFerries, elke minuut ververst&#8230;<\/p>\n","protected":false},"author":2,"featured_media":501,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_header_footer","meta":{"_kad_post_transparent":"","_kad_post_title":"hide","_kad_post_layout":"fullwidth","_kad_post_sidebar_id":"","_kad_post_content_style":"unboxed","_kad_post_vertical_padding":"","_kad_post_feature":"hide","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_kad_post_classname":"","footnotes":""},"class_list":["post-37","page","type-page","status-publish","has-post-thumbnail","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Vaartijden Duinkerken Dover: afvaarten vandaag en deze week<\/title>\n<meta name=\"description\" content=\"Alle afvaarten Duinkerken naar Dover: vandaag live en per dag voor de komende week, met de sluitingstijd van het inchecken en het tijdsverschil.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/dover-dunkirk.com\/nl\/vaarschema\/\" \/>\n<meta property=\"og:locale\" content=\"nl_NL\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Vaartijden Duinkerken Dover: afvaarten vandaag en deze week\" \/>\n<meta property=\"og:description\" content=\"Alle afvaarten Duinkerken naar Dover: vandaag live en per dag voor de komende week, met de sluitingstijd van het inchecken en het tijdsverschil.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/dover-dunkirk.com\/nl\/vaarschema\/\" \/>\n<meta property=\"og:site_name\" content=\"Duinkerken Dover Veerboot\" \/>\n<meta property=\"article:modified_time\" content=\"2026-09-28T20:05:39+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/dover-dunkirk.com\/nl\/wp-content\/uploads\/sites\/3\/2026\/09\/delft-seaways-bow-loading-ramp.webp\" \/>\n\t<meta property=\"og:image:width\" content=\"1400\" \/>\n\t<meta property=\"og:image:height\" content=\"1050\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/webp\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Geschatte leestijd\" \/>\n\t<meta name=\"twitter:data1\" content=\"2 minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/dover-dunkirk.com\\\/nl\\\/vaarschema\\\/\",\"url\":\"https:\\\/\\\/dover-dunkirk.com\\\/nl\\\/vaarschema\\\/\",\"name\":\"Vaartijden Duinkerken Dover: afvaarten vandaag en deze week\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/dover-dunkirk.com\\\/nl\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/dover-dunkirk.com\\\/nl\\\/vaarschema\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/dover-dunkirk.com\\\/nl\\\/vaarschema\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/dover-dunkirk.com\\\/nl\\\/wp-content\\\/uploads\\\/sites\\\/3\\\/2026\\\/09\\\/delft-seaways-bow-loading-ramp.webp\",\"datePublished\":\"2024-06-03T09:00:01+00:00\",\"dateModified\":\"2026-09-28T20:05:39+00:00\",\"description\":\"Alle afvaarten Duinkerken naar Dover: vandaag live en per dag voor de komende week, met de sluitingstijd van het inchecken en het tijdsverschil.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/dover-dunkirk.com\\\/nl\\\/vaarschema\\\/#breadcrumb\"},\"inLanguage\":\"nl-NL\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/dover-dunkirk.com\\\/nl\\\/vaarschema\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"nl-NL\",\"@id\":\"https:\\\/\\\/dover-dunkirk.com\\\/nl\\\/vaarschema\\\/#primaryimage\",\"url\":\"https:\\\/\\\/dover-dunkirk.com\\\/nl\\\/wp-content\\\/uploads\\\/sites\\\/3\\\/2026\\\/09\\\/delft-seaways-bow-loading-ramp.webp\",\"contentUrl\":\"https:\\\/\\\/dover-dunkirk.com\\\/nl\\\/wp-content\\\/uploads\\\/sites\\\/3\\\/2026\\\/09\\\/delft-seaways-bow-loading-ramp.webp\",\"width\":1400,\"height\":1050,\"caption\":\"De Delft Seaways aan de kade in Loon-Plage met de laadklep omlaag\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/dover-dunkirk.com\\\/nl\\\/vaarschema\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Van Duinkerken naar Dover\",\"item\":\"https:\\\/\\\/dover-dunkirk.com\\\/nl\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Vaartijden Duinkerken naar Dover\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/dover-dunkirk.com\\\/nl\\\/#website\",\"url\":\"https:\\\/\\\/dover-dunkirk.com\\\/nl\\\/\",\"name\":\"Duinkerken Dover Veerboot\",\"description\":\"Van Duinkerken naar Dover\",\"publisher\":{\"@id\":\"https:\\\/\\\/dover-dunkirk.com\\\/nl\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/dover-dunkirk.com\\\/nl\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"nl-NL\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/dover-dunkirk.com\\\/nl\\\/#organization\",\"name\":\"Van Duinkerken naar Dover\",\"alternateName\":\"Van Duinkerken naar Dover\",\"url\":\"https:\\\/\\\/dover-dunkirk.com\\\/nl\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"nl-NL\",\"@id\":\"https:\\\/\\\/dover-dunkirk.com\\\/nl\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/dover-dunkirk.com\\\/nl\\\/wp-content\\\/uploads\\\/sites\\\/3\\\/2025\\\/01\\\/D.png\",\"contentUrl\":\"https:\\\/\\\/dover-dunkirk.com\\\/nl\\\/wp-content\\\/uploads\\\/sites\\\/3\\\/2025\\\/01\\\/D.png\",\"width\":512,\"height\":512,\"caption\":\"Van Duinkerken naar Dover\"},\"image\":{\"@id\":\"https:\\\/\\\/dover-dunkirk.com\\\/nl\\\/#\\\/schema\\\/logo\\\/image\\\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Vaartijden Duinkerken Dover: afvaarten vandaag en deze week","description":"Alle afvaarten Duinkerken naar Dover: vandaag live en per dag voor de komende week, met de sluitingstijd van het inchecken en het tijdsverschil.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/dover-dunkirk.com\/nl\/vaarschema\/","og_locale":"nl_NL","og_type":"article","og_title":"Vaartijden Duinkerken Dover: afvaarten vandaag en deze week","og_description":"Alle afvaarten Duinkerken naar Dover: vandaag live en per dag voor de komende week, met de sluitingstijd van het inchecken en het tijdsverschil.","og_url":"https:\/\/dover-dunkirk.com\/nl\/vaarschema\/","og_site_name":"Duinkerken Dover Veerboot","article_modified_time":"2026-09-28T20:05:39+00:00","og_image":[{"width":1400,"height":1050,"url":"https:\/\/dover-dunkirk.com\/nl\/wp-content\/uploads\/sites\/3\/2026\/09\/delft-seaways-bow-loading-ramp.webp","type":"image\/webp"}],"twitter_card":"summary_large_image","twitter_misc":{"Geschatte leestijd":"2 minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/dover-dunkirk.com\/nl\/vaarschema\/","url":"https:\/\/dover-dunkirk.com\/nl\/vaarschema\/","name":"Vaartijden Duinkerken Dover: afvaarten vandaag en deze week","isPartOf":{"@id":"https:\/\/dover-dunkirk.com\/nl\/#website"},"primaryImageOfPage":{"@id":"https:\/\/dover-dunkirk.com\/nl\/vaarschema\/#primaryimage"},"image":{"@id":"https:\/\/dover-dunkirk.com\/nl\/vaarschema\/#primaryimage"},"thumbnailUrl":"https:\/\/dover-dunkirk.com\/nl\/wp-content\/uploads\/sites\/3\/2026\/09\/delft-seaways-bow-loading-ramp.webp","datePublished":"2024-06-03T09:00:01+00:00","dateModified":"2026-09-28T20:05:39+00:00","description":"Alle afvaarten Duinkerken naar Dover: vandaag live en per dag voor de komende week, met de sluitingstijd van het inchecken en het tijdsverschil.","breadcrumb":{"@id":"https:\/\/dover-dunkirk.com\/nl\/vaarschema\/#breadcrumb"},"inLanguage":"nl-NL","potentialAction":[{"@type":"ReadAction","target":["https:\/\/dover-dunkirk.com\/nl\/vaarschema\/"]}]},{"@type":"ImageObject","inLanguage":"nl-NL","@id":"https:\/\/dover-dunkirk.com\/nl\/vaarschema\/#primaryimage","url":"https:\/\/dover-dunkirk.com\/nl\/wp-content\/uploads\/sites\/3\/2026\/09\/delft-seaways-bow-loading-ramp.webp","contentUrl":"https:\/\/dover-dunkirk.com\/nl\/wp-content\/uploads\/sites\/3\/2026\/09\/delft-seaways-bow-loading-ramp.webp","width":1400,"height":1050,"caption":"De Delft Seaways aan de kade in Loon-Plage met de laadklep omlaag"},{"@type":"BreadcrumbList","@id":"https:\/\/dover-dunkirk.com\/nl\/vaarschema\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Van Duinkerken naar Dover","item":"https:\/\/dover-dunkirk.com\/nl\/"},{"@type":"ListItem","position":2,"name":"Vaartijden Duinkerken naar Dover"}]},{"@type":"WebSite","@id":"https:\/\/dover-dunkirk.com\/nl\/#website","url":"https:\/\/dover-dunkirk.com\/nl\/","name":"Duinkerken Dover Veerboot","description":"Van Duinkerken naar Dover","publisher":{"@id":"https:\/\/dover-dunkirk.com\/nl\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/dover-dunkirk.com\/nl\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"nl-NL"},{"@type":"Organization","@id":"https:\/\/dover-dunkirk.com\/nl\/#organization","name":"Van Duinkerken naar Dover","alternateName":"Van Duinkerken naar Dover","url":"https:\/\/dover-dunkirk.com\/nl\/","logo":{"@type":"ImageObject","inLanguage":"nl-NL","@id":"https:\/\/dover-dunkirk.com\/nl\/#\/schema\/logo\/image\/","url":"https:\/\/dover-dunkirk.com\/nl\/wp-content\/uploads\/sites\/3\/2025\/01\/D.png","contentUrl":"https:\/\/dover-dunkirk.com\/nl\/wp-content\/uploads\/sites\/3\/2025\/01\/D.png","width":512,"height":512,"caption":"Van Duinkerken naar Dover"},"image":{"@id":"https:\/\/dover-dunkirk.com\/nl\/#\/schema\/logo\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/dover-dunkirk.com\/nl\/wp-json\/wp\/v2\/pages\/37","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dover-dunkirk.com\/nl\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/dover-dunkirk.com\/nl\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/dover-dunkirk.com\/nl\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/dover-dunkirk.com\/nl\/wp-json\/wp\/v2\/comments?post=37"}],"version-history":[{"count":36,"href":"https:\/\/dover-dunkirk.com\/nl\/wp-json\/wp\/v2\/pages\/37\/revisions"}],"predecessor-version":[{"id":601,"href":"https:\/\/dover-dunkirk.com\/nl\/wp-json\/wp\/v2\/pages\/37\/revisions\/601"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/dover-dunkirk.com\/nl\/wp-json\/wp\/v2\/media\/501"}],"wp:attachment":[{"href":"https:\/\/dover-dunkirk.com\/nl\/wp-json\/wp\/v2\/media?parent=37"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}