Find A Doctor Canada

A calm turquoise lake surrounded by evergreen forest and the Canadian Rockies
Find A Doctor Canada Blog

Practical guidance.
Calmer next steps.

Independent city guides, doctor-search tips and healthcare-navigation articles to help Canadians organize their search for primary care.

  • Independent information
  • City-by-city resources
  • Not medical advice

Browse the blog

Filter published articles by topic, province or city.

Loading published blog articles...

Featured blog article

The newest published post matching your filters.

Latest blog articles

New posts appear automatically after they are published.

View all blog posts →
More published blog articles will appear here automatically.

Keep your doctor search moving

Use the free tools to organize your search, or subscribe for new healthcare navigation articles and updates.

Read the article →
`; } function cardMarkup(post) { const title = textOnly(post?.title?.rendered || "Published blog article"); const link = safeURL(post?.link); const image = postImage(post); const category = topicTerm(post); const categoryName = textOnly(category.name || "Blog article"); const date = displayDate(post); const location = locationMeta(post); const summary = excerpt(post) || "Practical information and clear next steps for your doctor search."; return ` `; } function updateStatus(count) { if (!elements.status) return; const active = [state.topic, state.province, state.city, state.search].filter(Boolean); elements.status.textContent = `${count} published blog article${count === 1 ? "" : "s"}${active.length ? " matched your filters" : " available"}.`; } function updateActiveTopic() { $$("[data-topic]").forEach(link => { const active = (link.dataset.topic || "") === state.topic; link.classList.toggle("is-active", active); if (active) link.setAttribute("aria-current", "page"); else link.removeAttribute("aria-current"); }); } function render() { if (!state.loaded) return; const posts = filteredPosts(); updateStatus(posts.length); updateActiveTopic(); if (!posts.length) { elements.featured.innerHTML = `
No published blog article matches those filters. Try another topic, province, city or search term.
`; elements.articles.innerHTML = `
Clear one or more filters to see additional blog articles.
`; elements.loadWrap.hidden = true; return; } elements.featured.innerHTML = featuredMarkup(posts[0]); const remaining = posts.slice(1); const visible = remaining.slice(0, state.visible); elements.articles.innerHTML = visible.length ? visible.map(cardMarkup).join("") : `
More published blog articles will appear here automatically.
`; elements.loadWrap.hidden = remaining.length <= state.visible; } function syncURL() { if (!window.history?.replaceState) return; const url = new URL(window.location.href); const values = { topic: state.topic, province: state.province, city: state.city, q: state.search, sort: state.sort === "newest" ? "" : state.sort }; Object.entries(values).forEach(([key, value]) => { if (value) url.searchParams.set(key, value); else url.searchParams.delete(key); }); url.hash = "fadc-blog-results"; window.history.replaceState({}, "", url); } function applyState({ scroll = false } = {}) { state.visible = 9; render(); syncURL(); if (scroll) { $(".fadc-content")?.scrollIntoView({ behavior: "smooth", block: "start" }); } } function categoryLink(definition) { const category = matchingCategory(definition); return category ? safeURL(category.link, `/category/${definition.slug}/`) : `/category/${definition.slug}/`; } function categoryCount(definition) { const category = matchingCategory(definition); return category ? Number(category.count || 0) : 0; } function taxonomyTerm(definition, taxonomy) { const map = taxonomy === "post_city" ? state.cityBySlug : state.provinceBySlug; const accepted = [definition.slug, ...(definition.aliases || [])]; for (const slug of accepted) { if (map.has(slug)) return map.get(slug); } return null; } function taxonomyLink(definition, taxonomy) { const term = taxonomyTerm(definition, taxonomy); const path = taxonomy === "post_city" ? "city" : taxonomy; return term ? safeURL(term.link, `/${path}/${definition.slug}/`) : `/${path}/${definition.slug}/`; } function taxonomyCount(definition, taxonomy) { const term = taxonomyTerm(definition, taxonomy); return term ? Number(term.count || 0) : 0; } function updateArchiveLinks() { if (elements.topicLinks) { elements.topicLinks.innerHTML = topicDefinitions .filter(definition => categoryCount(definition) > 0) .map(definition => `
  • ${escapeHTML(definition.label)}${categoryCount(definition)}
  • `).join(""); } if (elements.cityLinks) { elements.cityLinks.innerHTML = [...cityDefinitions] .filter(definition => taxonomyCount(definition, "post_city") > 0) .sort((left, right) => left.label.localeCompare(right.label)) .map(definition => `
  • ${escapeHTML(definition.label)}${taxonomyCount(definition, "post_city")}
  • `).join(""); } } function refreshCityOptions({ province = elements.province.value, preserve = true } = {}) { const current = preserve ? elements.city.value : ""; const allowedCities = cityDefinitions .filter(definition => taxonomyCount(definition, "post_city") > 0) .filter(definition => !province || definition.province === province) .sort((left, right) => left.label.localeCompare(right.label)); if (province) { const provinceName = definitionFor(provinceDefinitions, province)?.label || "selected province"; elements.city.innerHTML = [ ``, ...allowedCities.map(definition => ``) ].join(""); } else { const groups = provinceDefinitions.map(provinceDefinition => { const cities = cityDefinitions .filter(definition => taxonomyCount(definition, "post_city") > 0) .filter(definition => definition.province === provinceDefinition.slug) .sort((left, right) => left.label.localeCompare(right.label)); if (!cities.length) return ""; return `${cities.map(definition => ``).join("")}`; }).join(""); elements.city.innerHTML = `${groups}`; } elements.city.value = allowedCities.some(definition => definition.slug === current) ? current : ""; return elements.city.value; } function restoreFromURL() { const params = new URLSearchParams(window.location.search); state.topic = params.get("topic") || ""; state.province = params.get("province") || ""; state.city = params.get("city") || ""; state.search = params.get("q") || ""; state.sort = ["newest", "oldest", "title"].includes(params.get("sort")) ? params.get("sort") : "newest"; if (!topicDefinitions.some(item => item.slug === state.topic)) state.topic = ""; if (!provinceDefinitions.some(item => item.slug === state.province)) state.province = ""; if (!cityDefinitions.some(item => item.slug === state.city)) state.city = ""; const restoredCity = definitionFor(cityDefinitions, state.city); if (restoredCity && state.province && restoredCity.province !== state.province) state.city = ""; elements.searchInput.value = state.search; elements.province.value = state.province; refreshCityOptions({ province: state.province, preserve: false }); elements.city.value = state.city; elements.sort.value = state.sort; } elements.searchForm?.addEventListener("submit", event => { if (!state.loaded) return; event.preventDefault(); state.search = elements.searchInput.value.trim(); applyState({ scroll: true }); }); elements.topics?.addEventListener("click", event => { const link = event.target.closest("[data-topic]"); if (!link || !state.loaded) return; event.preventDefault(); state.topic = link.dataset.topic || ""; applyState({ scroll: true }); }); elements.filterForm?.addEventListener("submit", event => { if (!state.loaded) return; event.preventDefault(); state.province = elements.province.value; state.city = elements.city.value; state.sort = elements.sort.value; applyState({ scroll: true }); }); elements.province?.addEventListener("change", () => { refreshCityOptions({ province: elements.province.value }); }); elements.sort?.addEventListener("change", () => { if (!state.loaded) return; state.sort = elements.sort.value; applyState(); }); elements.clear?.addEventListener("click", () => { state.topic = ""; state.province = ""; state.city = ""; state.search = ""; state.sort = "newest"; elements.searchInput.value = ""; elements.province.value = ""; refreshCityOptions({ province: "", preserve: false }); elements.sort.value = "newest"; applyState({ scroll: true }); }); elements.loadMore?.addEventListener("click", () => { state.visible += 9; render(); }); restoreFromURL(); async function fetchCollection(endpoint, maximumPages = 5) { const requestPage = async page => { const separator = endpoint.includes("?") ? "&" : "?"; const response = await fetch(`${endpoint}${separator}page=${page}`, { credentials: "same-origin", headers: { Accept: "application/json" } }); if (!response.ok) throw new Error(`REST feed returned ${response.status}`); return { response, items: await response.json() }; }; const first = await requestPage(1); const totalPages = Math.min( Math.max(Number(first.response.headers.get("X-WP-TotalPages")) || 1, 1), maximumPages ); if (totalPages === 1) return Array.isArray(first.items) ? first.items : []; const remaining = await Promise.all( Array.from({ length: totalPages - 1 }, (_, index) => requestPage(index + 2)) ); return [first, ...remaining].flatMap(result => Array.isArray(result.items) ? result.items : []); } const siteOrigin = window.location.protocol === "file:" ? "https://findadoctorcanada.ca" : window.location.origin; const postsURL = `${siteOrigin}/wp-json/wp/v2/posts?per_page=100&_embed=1&status=publish`; function refreshVisibleTaxonomyControls() { const visibleTopics = new Set( topicDefinitions .filter(definition => categoryCount(definition) > 0) .map(definition => definition.slug) ); elements.topics?.querySelectorAll("[data-topic]").forEach(link => { const slug = link.dataset.topic || ""; link.hidden = Boolean(slug) && !visibleTopics.has(slug); }); const currentProvince = state.province; const availableProvinces = provinceDefinitions .filter(definition => taxonomyCount(definition, "province") > 0); elements.province.innerHTML = [ '', ...availableProvinces.map(definition => `` ) ].join(""); if (availableProvinces.some(definition => definition.slug === currentProvince)) { elements.province.value = currentProvince; } else { state.province = ""; elements.province.value = ""; } } function collectEmbeddedTerms(posts, taxonomy) { const terms = new Map(); posts.forEach(post => { const seen = new Set(); postTerms(post, taxonomy).forEach(term => { if (!term?.slug || seen.has(term.slug)) return; seen.add(term.slug); const current = terms.get(term.slug) || { ...term, count: 0 }; current.count += 1; terms.set(term.slug, current); }); }); return [...terms.values()]; } fetchCollection(postsURL) .then(posts => { state.posts = Array.isArray(posts) ? posts : []; state.categories = collectEmbeddedTerms(state.posts, "category"); state.cities = collectEmbeddedTerms(state.posts, "post_city"); state.provinces = collectEmbeddedTerms(state.posts, "province"); state.categoryById = new Map(state.categories.map(category => [Number(category.id), category])); state.categoryBySlug = new Map(state.categories.map(category => [String(category.slug), category])); state.cityBySlug = new Map(state.cities.map(term => [String(term.slug), term])); state.provinceBySlug = new Map(state.provinces.map(term => [String(term.slug), term])); refreshVisibleTaxonomyControls(); state.loaded = true; refreshCityOptions({ province: state.province, preserve: true }); if (state.city) elements.city.value = state.city; updateArchiveLinks(); render(); }) .catch(error => { console.warn("FADC Blog could not load the WordPress post feed.", error); if (elements.status) { elements.status.textContent = "Live post filtering is temporarily unavailable. The normal article and archive links remain available."; } }); })();