Day and Night Tour of Niagara Falls Canada - Combo Tour

Day and Night Combo Tour of Niagara Falls, Canada

280 reviews for this tour

Get the best of both worlds – a day and night tour of Niagara Falls. Travel above, behind, and right up close to these majestic, cascading waterfalls during the day. When the sunsets, watch as brightly coloured lights transform the Falls into a sight that is beyond words.

Key Details
duration
Duration: 6.5 Hours
cancellation
Free cancellation: 100% refund when cancelled at least 24 hours in advance

What you'll see

Niagara City Cruises in 2024
Experience Included

Niagara City Cruises

Departing from Niagara Falls, Canada - on the Hornblower you will ride into the mist of Niagara Fall...

Journey Behind the Falls in 2024

Journey Behind the Falls

At Journey Behind the Falls, you’ll descend about 125 ft. (approximately 40 m) to explore cave-like ...

Table Rock House Restaurant in 2024

Table Rock House Restaurant

Table Rock House Restaurant serves up locally sourced, internationally inspired menus with an incred...

Illumination Tower in 2024

Illumination Tower

At Illumination Tower, you’ll have an exclusive opportunity to control the magnificent light show th...

Skylon Tower in 2024

Skylon Tower

The Skylon Tower offers an impressive birds-eye-view of both the American and Canadian sides of Niag...

Our Guest Reviews

280 reviews for this Tour
A
aimnoooo
October 09, 2025
reviews

5/5

aimnooooooooooooooooo algolia PR review

A
aimnooo
September 23, 2025
reviews

5/5

a little sympathy i hope you can show me

A
aimno
September 23, 2025
reviews

5/5

could you find a way to let me down slowlyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy

aimno enjoying Day and Night Combo Tour of Niagara Falls, Canada 2025-09-23
A
aimn
September 23, 2025
reviews

5/5

normal review

Q
qazxsw
July 04, 2025
reviews

4/5

const fetchReviewAggregate = async () => { try { if (!toursStrapiId) return; console.log('fetchReviewAggregate called for ID:', toursStrapiId); const response = await client.query({ query: FETCH_REVIEW_AGGREGATE_TOURS, variables: { id: toursStrapiId }, fetchPolicy: 'no-cache' }); console.log('fetchReviewAggregate response:', response); const aggregate = response.data?.strapi_reviews_aggregate?.aggregate; console.log('fetchReviewAggregate aggregate:', aggregate); const newCount = aggregate?.count || 0; const newRating = aggregate?.avg?.rating ? parseFloat(aggregate.avg.rating.toFixed(1)) : 0; console.log('Setting totalReviewsCount to:', newCount); console.log('Setting averageRating to:', newRating); setTotalReviewsCount(newCount); setAverageRating(newRating); } catch (error) { console.error('Failed to fetch review aggregate:', error); } }; const fetchRatingCounts = async () => { try { console.log('fetchRatingCounts called for ID:', toursStrapiId); const { data } = await client.query({ query: FETCH_REVIEW_COUNTS_BY_RATING, variables: { id: toursStrapiId }, fetchPolicy: 'no-cache' }); const reviews = data.strapi_reviews; console.log('fetchRatingCounts reviews:', reviews); const counts: { [key: number]: number } = { 1: 0, 2: 0, 3: 0, 4: 0, 5: 0 }; reviews.forEach((review: any) => { const rating = review.rating; let starCategory: number; if (rating >= 0 && rating < 2) { starCategory = 1; } else if (rating >= 2 && rating < 3) { starCategory = 2; } else if (rating >= 3 && rating < 4) { starCategory = 3; } else if (rating >= 4 && rating < 5) { starCategory = 4; } else if (rating === 5) { starCategory = 5; } else { return; } counts[starCategory]++; }); console.log('fetchRatingCounts setting counts:', counts); setRatingCounts(counts); } catch (error) { console.error('Error fetching rating counts:', error); } }; useEffect(() => { // Reset states when the route changes setShowPax(false); setIsPaxVisible(false); }, [router.query.slug]); const fetchReviews = async () => { try { setLoader(true); if (!toursStrapiId) { console.error('No strapi product ID found'); setLoader(false); return; } // Build where clause for filtering const whereClause: any = { product: { _eq: toursStrapiId } }; // Add rating filter if selected if (selectedRating && selectedRating !== 'all-stars') { whereClause.rating = { _eq: parseInt(selectedRating) }; } // Calculate offset for pagination const offset = (currentPage - 1) * itemsPerPage; // Fetch reviews with GraphQL query const response = await client.query({ query: FETCH_REVIEWS, variables: { limit: itemsPerPage, offset: offset, order_by: [{ rating: 'desc' }, { created_at: 'desc' }], where: whereClause }, fetchPolicy: 'no-cache' }); if (response?.data?.strapi_reviews) { const reviews = response.data.strapi_reviews; // Process reviews to match expected format const processedReviews = reviews.map((review: any) => ({ ...review, name: review.traveller, created_at: review.created_at })); setReviews(processedReviews); // Calculate best review (highest rating, then most recent) const sortedByRating = [...reviews].sort((a, b) => { if (b.rating !== a.rating) return b.rating - a.rating; return ( new Date(b.created_at).getTime() - new Date(a.created_at).getTime() ); }); const eligibleReviews = sortedByRating.filter( r => typeof r.review === 'string' && r.review.trim().length > 100 ); if (eligibleReviews.length > 0) { setBestReview({ ...eligibleReviews[0], name: eligibleReviews[0].traveller }); setSecondMostPositiveReview( eligibleReviews[1] ? { ...eligibleReviews[1], name: eligibleReviews[1].traveller } : undefined ); setPositiveReview( eligibleReviews[2] ? { ...eligibleReviews[2], name: eligibleReviews[2].traveller } : undefined ); } else { // Optional: explicitly clear previous reviews if no eligible ones exist setBestReview(undefined); setSecondMostPositiveReview(undefined); setPositiveReview(undefined); } // Update review counts for pagination - only for filtered reviews if (selectedRating && selectedRating !== 'all-stars') { // For filtered reviews, we need to count how many match the filter const filteredCountResponse = await client.query({ query: FETCH_REVIEWS, variables: { offset: 0, where: { product: { _eq: toursStrapiId }, rating: { _eq: parseInt(selectedRating) } } }, fetchPolicy: 'no-cache' }); const filteredCount = filteredCountResponse?.data?.strapi_reviews?.length || 0; setReviewsCount(filteredCount); } } } catch (error) { console.error('Error fetching reviews:', error); } setLoader(false); }; useEffect(() => { fetchReviews(); }, [selectedRating, currentPage]); useEffect(() => { fetchReviewAggregate(); fetchRatingCounts(); }, []);

Q
qazxsw
July 04, 2025
reviews

4.5/5

dgtjy tht

Newsletter

From $279 USD