top of page
Anchor 1
TOP
directory.png

Explore, plan, travel.

Maine Cedar Log Moose Co

★ Trail Partner

Artisans & Makers

Mile 214 · Rte 2

Molunkus

Hand-crafted cedar log moose, bears, and folk-art sculptures built from real Maine cedar. Located in Molunkus Township — the southern gateway to Aroostook County on Route 2. Home of the original 1937 Pine Tree Trail sign that sparked the modern revival of the Trail. A working Maine craft studio where every piece is shaped by hand.

mileBadge

mileBadge

mileBadge

🐾 Pet Friendly

♿ Accessible

Surface: Hard

Types: Standard 120v outlet

⚡ EV Charging

Recommended stops:

CTAanchor

Municipality

municipal-building-icon.png

Winthrop

Winthrop

Winthrop

import wixLocation from 'wix-location'; import wixData from 'wix-data'; import { authentication } from 'wix-members'; import { getCurrentTripWithStops, createTripWithFirstStop } from 'backend/tripPlanner'; import { addStop, removeStopByListingId } from 'backend/tripStops'; import { getTrailMileBadge, getBadgeColors } from 'public/trailMileBadge'; function safe(fn = () => null) { try { fn(); } catch (e) { console.warn('[directory safe]', e && e.message); } } async function safeAsync(fn = async () => null) { try { return await fn(); } catch (e) { console.warn('[directory safeAsync]', e && e.message); if (e && /EDIT_LOCKOUT/.test(e.message)) { showNotice(e.message, true); } else if (e && /ACTIVE_TRIP_EXISTS/.test(e.message)) { showNotice(e.message.replace(/^ACTIVE_TRIP_EXISTS:\s*/, ''), true); } return null; } } function alertError(actionLabel = 'Action', e = null) { if (e && /EDIT_LOCKOUT/.test(e.message)) { showNotice(e.message, true); } else if (e && /ACTIVE_TRIP_EXISTS/.test(e.message)) { showNotice(e.message.replace(/^ACTIVE_TRIP_EXISTS:\s*/, ''), true); } else { showNotice(actionLabel + ' failed. Please try again.', true); } } function showNotice(text = '', isError = false) { const id = isError ? '#txtDirNoticeError' : '#txtDirNoticeOk'; safe(() => { $w(id).text = String(text || ''); $w(id).expand(); }); setTimeout(() => safe(() => $w(id).collapse()), 3000); } const _addToTripBusy = new Set(); const LABEL_ADD = '+ Add to Trip Planner'; const LABEL_REMOVE = '\u2212 Remove from Planner'; const CATEGORY_COLORS = { 'food & beverage': { bg: '#e74c3c', text: '#FFFFFF' }, 'retail': { bg: '#27ae60', text: '#FFFFFF' }, 'services': { bg: '#3498db', text: '#FFFFFF' }, 'lodging': { bg: '#8e44ad', text: '#FFFFFF' }, 'recreation': { bg: '#e67e22', text: '#FFFFFF' }, 'events': { bg: '#f39c12', text: '#FFFFFF' }, 'real estate': { bg: '#95a5a6', text: '#FFFFFF' }, 'landmarks': { bg: '#6B7B8D', text: '#FFFFFF' }, 'trails': { bg: '#2E8B57', text: '#FFFFFF' }, 'boat access': { bg: '#4682B4', text: '#FFFFFF' }, 'campgrounds': { bg: '#4A5D23', text: '#FFFFFF' }, 'breweries & wineries': { bg: '#8B0000', text: '#FFFFFF' }, 'artisans & makers': { bg: '#6B2D5B', text: '#FFFFFF' }, 'maine guides': { bg: '#556B2F', text: '#FFFFFF' } }; function getCategoryColor(category) { const c = String(category || '').toLowerCase(); return CATEGORY_COLORS[c] || { bg: '#666666', text: '#FFFFFF' }; } const _stopsByListing = new Map(); async function loadCurrentTripStops() { let loggedIn = false; try { loggedIn = authentication.loggedIn(); } catch (e) { loggedIn = false; } if (!loggedIn) return; const current = await safeAsync(async () => await getCurrentTripWithStops()); if (current && current.currentTrip) { (current.currentStops || []).forEach(s => { if (s.listingId) _stopsByListing.set(s.listingId, s._id); }); } } function refreshAllCardLabels() { safe(() => { $w('#repBusinesses').forEachItem(($item, itemData) => { const isAdded = !!(itemData.listingId && _stopsByListing.has(itemData.listingId)); safe(() => { $item('#dirBtnAddToTrip').label = isAdded ? LABEL_REMOVE : LABEL_ADD; }); }); }); safe(() => { $w('#repLandmarks').forEachItem(($item, itemData) => { const isAdded = !!(itemData.listingId && _stopsByListing.has(itemData.listingId)); safe(() => { $item('#dirLmBtnAddToTrip').label = isAdded ? LABEL_REMOVE : LABEL_ADD; }); }); }); } function extractImageUrl(value = null) { if (!value) return ''; if (typeof value === 'string') return value; if (typeof value === 'object') { return value.src || value.url || value.fileUrl || value.file_url || ''; } return ''; } function buildStopPayloadFromRow(row = {}, source = 'BUSINESS') { const lat = (typeof row.latitude === 'number') ? row.latitude : (typeof row.pinLat === 'number') ? row.pinLat : null; const lng = (typeof row.longitude === 'number') ? row.longitude : (typeof row.pinLng === 'number') ? row.pinLng : null; const title = row.title_fld || row.title || ''; const description = row.description_fld || row.description || ''; const addressParts = [row.streetAddress, row.town, row.state, row.zipCode].filter(Boolean); const address = addressParts.join(', '); return { source, sourceItemId: row._id || '', title, town: row.town || '', primaryImageUrl: extractImageUrl(row.primaryImage || row.image_fld || null), category: row.category || '', listingId: row.listingId || '', description, address, phone: row.phone || '', website: row.website || '', hoursOfOperation: row.hoursOfOperation || '', petFriendly: !!row.petFriendly, wheelchairAccessible: row.wheelchairAccessible || null, lat, lng }; } function buildMapQueryString(row = {}) { const lat = (typeof row.latitude === 'number') ? row.latitude : (typeof row.pinLat === 'number') ? row.pinLat : null; const lng = (typeof row.longitude === 'number') ? row.longitude : (typeof row.pinLng === 'number') ? row.pinLng : null; const name = row.title_fld || row.title || ''; const params = []; if (lat != null && lng != null) { params.push(`lat=${encodeURIComponent(lat)}`); params.push(`lng=${encodeURIComponent(lng)}`); } if (row.listingId) params.push(`listingId=${encodeURIComponent(row.listingId)}`); if (row.category) params.push(`category=${encodeURIComponent(row.category)}`); if (name) params.push(`name=${encodeURIComponent(name)}`); return params.length ? `?${params.join('&')}` : ''; } async function handleAddToTrip(row = {}, source = 'BUSINESS', $btn = null) { if (!row || !row._id) { showNotice('Item data not loaded. Please try again.', true); return; } if (_addToTripBusy.has(row._id)) return; let loggedIn = false; try { loggedIn = authentication.loggedIn(); } catch (e) { loggedIn = false; } if (!loggedIn) { try { await authentication.promptLogin(); } catch (e) { return; } } _addToTripBusy.add(row._id); if ($btn) safe(() => $btn.disable()); try { const current = await getCurrentTripWithStops(); const tripId = (current && current.currentTrip) ? current.currentTrip._id : null; const existingStop = (tripId && row.listingId) ? (current.currentStops || []).find(s => s.listingId === row.listingId) : null; if (existingStop) { await removeStopByListingId({ tripId, listingId: row.listingId }); if (row.listingId) _stopsByListing.delete(row.listingId); if ($btn) safe(() => { $btn.label = LABEL_ADD; }); showNotice('Removed!'); } else { const stop = buildStopPayloadFromRow(row, source); let newStopId = null; if (tripId) { const inserted = await addStop({ tripId, stop }); newStopId = inserted && inserted._id; } else { const result = await createTripWithFirstStop({ tripName: 'My Trip', stop }); newStopId = result && result.stop && result.stop._id; } if (row.listingId) _stopsByListing.set(row.listingId, newStopId || true); if ($btn) safe(() => { $btn.label = LABEL_REMOVE; }); showNotice('Added!'); } } catch (e) { console.warn('[directory handleAddToTrip]', e && e.message); let msg = 'Add to trip'; if (e && /DUPLICATE_STOP/.test(e.message)) msg = 'Already on your trip'; if (e && /STOP_LIMIT/.test(e.message)) msg = 'Trip is full (20 stops max)'; alertError(msg, e); } finally { _addToTripBusy.delete(row._id); if ($btn) safe(() => $btn.enable()); } } function wireBusinessCard($item, row = {}) { safe(() => { const badge = getTrailMileBadge(row); if (badge.show) { const colors = getBadgeColors(badge.severity); $item('#dirTxtMile').text = badge.text; safe(() => { $item('#mileBox').style.backgroundColor = colors.bg; }); safe(() => { $item('#mileBox').style.borderColor = colors.border; }); safe(() => { $item('#dirTxtMile').style.color = colors.text; }); $item('#mileBox').expand(); } else { $item('#mileBox').collapse(); } }); safe(() => { $item('#dirBtnViewMap').onClick(() => { const qs = buildMapQueryString(row); wixLocation.to(`/trail-map${qs}${qs ? '&' : '?'}from=directory#mapAnchor`); }); }); safe(() => { if (row.category) { const catColors = getCategoryColor(row.category); $item('#dirBadgeCategory').text = row.category; safe(() => { $item('#dirCategoryPill').style.backgroundColor = catColors.bg; }); safe(() => { $item('#dirBadgeCategory').style.color = catColors.text; }); $item('#dirCategoryPill').expand(); } else { $item('#dirCategoryPill').collapse(); } }); safe(() => { if (row.petFriendly) { $item('#petBadge').expand(); } else { $item('#petBadge').collapse(); } const rawTags = row.wheelchairAccessible; let surfaceTags = []; if (Array.isArray(rawTags)) { surfaceTags = rawTags.filter(t => t); } else if (typeof rawTags === 'string' && rawTags) { surfaceTags = rawTags.split(',').map(t => t.trim()).filter(t => t); } const hasAccessibility = surfaceTags.length > 0; const realTags = surfaceTags.filter(t => t !== 'N/A'); if (hasAccessibility) { $item('#wheelchairBadge').expand(); } else { $item('#wheelchairBadge').collapse(); } if (realTags.length > 0) { $item('#dirTxtSurface').text = 'Surface: ' + realTags.join(', '); $item('#dirTxtSurface').expand(); } else { $item('#dirTxtSurface').collapse(); } }); safe(() => { const $btn = $item('#dirBtnAddToTrip'); const isAdded = !!(row.listingId && _stopsByListing.has(row.listingId)); safe(() => { $btn.label = isAdded ? LABEL_REMOVE : LABEL_ADD; }); $btn.onClick(async () => { await handleAddToTrip(row, 'BUSINESS', $btn); }); }); safe(() => $item('#dirBoxExpanded').collapse()); let bizExpanded = false; safe(() => { $item('#dirBtnExpand').onClick(() => { bizExpanded = !bizExpanded; if (bizExpanded) { safe(() => { if (row.streetAddress) { $item('#text263').text = 'Address: ' + row.streetAddress; $item('#text263').expand(); } else { $item('#text263').collapse(); } if (row.phone) { $item('#text264').text = 'Phone: ' + row.phone; $item('#text264').expand(); } else { $item('#text264').collapse(); } if (row.hoursOfOperation) { $item('#text265').text = 'Hours: ' + row.hoursOfOperation; $item('#text265').expand(); } else { $item('#text265').collapse(); } }); safe(() => { if (row.website) { $item('#dirBtnVisitWebsite').link = row.website; $item('#dirBtnVisitWebsite').target = '_blank'; $item('#dirBtnVisitWebsite').show(); } else { $item('#dirBtnVisitWebsite').hide(); } }); safe(() => $item('#dirBoxExpanded').expand()); safe(() => { $item('#dirBtnExpand').label = 'See less'; }); } else { safe(() => $item('#dirBoxExpanded').collapse()); safe(() => { $item('#dirBtnExpand').label = 'See more'; }); } }); }); } function wireLandmarkCard($item, row = {}) { safe(() => { const badge = getTrailMileBadge(row); if (badge.show) { const colors = getBadgeColors(badge.severity); $item('#dirLmTxtMile').text = badge.text; safe(() => { $item('#mileLmBox').style.backgroundColor = colors.bg; }); safe(() => { $item('#mileLmBox').style.borderColor = colors.border; }); safe(() => { $item('#dirLmTxtMile').style.color = colors.text; }); $item('#mileLmBox').expand(); } else { $item('#mileLmBox').collapse(); } }); safe(() => { $item('#dirLmBtnViewMap').onClick(() => { const qs = buildMapQueryString(row); wixLocation.to(`/trail-map${qs}${qs ? '&' : '?'}from=directory#mapAnchor`); }); }); safe(() => { if (row.category) { const catColors = getCategoryColor(row.category); $item('#dirLmBadgeCategory').text = row.category; safe(() => { $item('#dirLmCategoryPill').style.backgroundColor = catColors.bg; }); safe(() => { $item('#dirLmBadgeCategory').style.color = catColors.text; }); $item('#dirLmCategoryPill').expand(); } else { $item('#dirLmCategoryPill').collapse(); } }); safe(() => { if (row.petFriendly) { $item('#lmPetBadge').expand(); } else { $item('#lmPetBadge').collapse(); } const rawTags = row.wheelchairAccessible; let surfaceTags = []; if (Array.isArray(rawTags)) { surfaceTags = rawTags.filter(t => t); } else if (typeof rawTags === 'string' && rawTags) { surfaceTags = rawTags.split(',').map(t => t.trim()).filter(t => t); } const hasAccessibility = surfaceTags.length > 0; const realTags = surfaceTags.filter(t => t !== 'N/A'); if (hasAccessibility) { $item('#lmWheelchairBadge').expand(); } else { $item('#lmWheelchairBadge').collapse(); } if (realTags.length > 0) { $item('#dirLmTxtSurface').text = 'Surface: ' + realTags.join(', '); $item('#dirLmTxtSurface').expand(); } else { $item('#dirLmTxtSurface').collapse(); } }); safe(() => { const $btn = $item('#dirLmBtnAddToTrip'); const isAdded = !!(row.listingId && _stopsByListing.has(row.listingId)); safe(() => { $btn.label = isAdded ? LABEL_REMOVE : LABEL_ADD; }); $btn.onClick(async () => { await handleAddToTrip(row, 'LANDMARK', $btn); }); }); safe(() => $item('#dirLmBoxExpanded').collapse()); let lmExpanded = false; safe(() => { $item('#dirLmBtnExpand').onClick(() => { lmExpanded = !lmExpanded; if (lmExpanded) { safe(() => { if (row.streetAddress) { $item('#text260').text = 'Address: ' + row.streetAddress; $item('#text260').expand(); } else { $item('#text260').collapse(); } if (row.phone) { $item('#text261').text = 'Phone: ' + row.phone; $item('#text261').expand(); } else { $item('#text261').collapse(); } if (row.hoursOfOperation) { $item('#text262').text = 'Hours: ' + row.hoursOfOperation; $item('#text262').expand(); } else { $item('#text262').collapse(); } }); safe(() => { if (row.website) { $item('#dirLmBtnVisitWebsite').link = row.website; $item('#dirLmBtnVisitWebsite').target = '_blank'; $item('#dirLmBtnVisitWebsite').show(); } else { $item('#dirLmBtnVisitWebsite').hide(); } }); safe(() => $item('#dirLmBoxExpanded').expand()); safe(() => { $item('#dirLmBtnExpand').label = 'See less'; }); } else { safe(() => $item('#dirLmBoxExpanded').collapse()); safe(() => { $item('#dirLmBtnExpand').label = 'See more'; }); } }); }); } $w.onReady(function () { safe(() => { $w('#repBusinesses').onItemReady(($item, itemData) => { wireBusinessCard($item, itemData); }); }); safe(() => { $w('#repLandmarks').onItemReady(($item, itemData) => { wireLandmarkCard($item, itemData); }); }); safe(() => $w('#txtDirNoticeOk').collapse()); safe(() => $w('#txtDirNoticeError').collapse()); safe(() => { $w('#ddDirCategoryFilter').options = [ { label: 'All categories', value: '' }, ...Object.keys(CATEGORY_COLORS).map(c => { const t = c.replace(/\b\w/g, ch => ch.toUpperCase()); return { label: t, value: t }; }) ]; $w('#ddDirCategoryFilter').value = ''; }); function applyDirectoryFilters() { const q = String($w('#txtSearch').value || '').trim(); let selected = ''; safe(() => { selected = String($w('#ddDirCategoryFilter').value || ''); }); let bizFilter = wixData.filter(); let lmFilter = wixData.filter(); if (q) { bizFilter = bizFilter.and( wixData.filter().contains('title_fld', q).or(wixData.filter().contains('town', q)) ); lmFilter = lmFilter.and( wixData.filter().contains('title', q).or(wixData.filter().contains('town', q)) ); } if (selected) { bizFilter = bizFilter.and(wixData.filter().eq('category', selected)); lmFilter = lmFilter.and(wixData.filter().eq('category', selected)); } // Reset to page 1 for both sections when filters change safe(() => $w('#dataset1').setCurrentIndex(0)); safe(() => $w('#dataset2').setCurrentIndex(0)); safe(() => { $w('#pagination1').currentPage = 1; }); safe(() => { $w('#pagination3').currentPage = 1; }); safe(() => $w('#dataset1').setFilter(bizFilter)); safe(() => $w('#dataset2').setFilter(lmFilter)); } let _searchTimer = null; safe(() => { $w('#txtSearch').onInput(() => { if (_searchTimer) clearTimeout(_searchTimer); _searchTimer = setTimeout(applyDirectoryFilters, 150); }); }); safe(() => { $w('#ddDirCategoryFilter').onChange(applyDirectoryFilters); }); function applyDirSort() { let mode = ''; safe(() => { mode = String($w('#ddSort').value || ''); }); if (mode === 'alpha') { safe(() => $w('#dataset1').setSort(wixData.sort().ascending('title_fld'))); safe(() => $w('#dataset2').setSort(wixData.sort().ascending('title'))); return; } let sortObj = wixData.sort(); if (mode === 'south-north') sortObj = wixData.sort().ascending('trailMile'); else if (mode === 'north-south') sortObj = wixData.sort().descending('trailMile'); else if (mode === 'recent') sortObj = wixData.sort().descending('_createdDate'); safe(() => $w('#dataset1').setSort(sortObj)); safe(() => $w('#dataset2').setSort(sortObj)); } safe(() => { $w('#ddSort').onChange(applyDirSort); }); // Default dropdown value only. Initial sort handled by dataset settings. safe(() => { $w('#ddSort').value = 'south-north'; }); (async () => { await loadCurrentTripS

Landmarks, Trails, Boat Access and More:

Penobscot River Walkway

Trails

0.6 mi off · Mile 146 · Rte 2

Bangor

Riverfront trail system along the Penobscot River connecting downtown Bangor to the amphitheater and waterfront park. Combined Penobscot River Walkway and Riverfront Trail offer scenic access to concerts, events, and the working waterfront.

mileBadge

mileBadge

mileBadge

🐾 Pet Friendly

♿ Accessible

Surface: Hard

Penobscot River Access

Boat Access

Mile 146 · Rte 2

Bangor

City-maintained landing facility on the Penobscot River at Bangor's downtown waterfront. Dock and float access only — no launching ramp. All-tide access with toilet facilities on site. Hand-carry small craft only. Natural takeout point for paddlers coming downriver from Orono, Passadumkeag, or Lincoln.

mileBadge

mileBadge

mileBadge

🐾 Pet Friendly

♿ Accessible

Surface: Hard

Paul Bunyan

Landmarks

0.8 mi off · Mile 146 · Rte 2

Bangor

31-foot-tall fiberglass statue unveiled in 1959 on Bangor's 125th anniversary. Designed by J. Normand Martin. Featured in Stephen King's 1986 novel It. Free public landmark.

mileBadge

mileBadge

mileBadge

🐾 Pet Friendly

♿ Accessible

Surface: Hard

Cascade Park

Landmarks

Mile 148 · Rte 2

Bangor

Historic park with paved paths and a waterfall fountain typically running May through October. One of Bangor's oldest public parks. Free.

mileBadge

mileBadge

mileBadge

🐾 Pet Friendly

♿ Accessible

Surface: Hard

Mount Hope Cemetery

Landmarks

Mile 149 · Rte 2

Bangor

Second oldest garden cemetery in the United States. Designed by Charles G. Bryant in 1834. Gravesite of Hannibal Hamlin, 15th Vice President. Al Brady, FBI Public Enemy Number One, buried here 1937. Filming location for Stephen King's Pet Sematary (1989). National Register of Historic Places. Free.

mileBadge

mileBadge

mileBadge

🐾 Pet Friendly

♿ Accessible

Surface: Hard

Bangor City Forest & Orono Bog Boardwalk

Trails

1.7 mi off · Mile 152 · Rte 2

Bangor

City-maintained 680-acre urban forest featuring the Orono Bog Boardwalk — a mile-long raised boardwalk through a National Natural Landmark peat bog. Extensive trail network through mixed forest suitable for all ages.

mileBadge

mileBadge

mileBadge

🐾 Pet Friendly

♿ Accessible

Surface: Crushed Stone, Boardwalk

Penobscot River Access

Boat Access

Mile 153 · Rte 2

Orono

Hard ramp on the Penobscot River at Orono, maintained by PPL-Maine (Black Bear Hydro). 10' wide. 6 rig parking spaces. Penobscot mainstem access between Milford and Bangor.

mileBadge

mileBadge

mileBadge

🐾 Pet Friendly

♿ Accessible

Surface: Hard

Penobscot River Access

Boat Access

Mile 165 · Rte 2

Milford

Town-maintained hard ramp on the Penobscot River at Milford. 10' wide, 110' long, 14% grade. 13 rig parking spaces, fully accessible. Penobscot mainstem access between Old Town and Greenbush.

mileBadge

mileBadge

mileBadge

🐾 Pet Friendly

♿ Accessible

Surface: Hard

Penobscot River Access

Boat Access

Mile 177 · Rte 2

Passadumkeag

Town-maintained hard ramp on the Penobscot River at Passadumkeag village. 10' wide, 73' long, 13% grade. 4 rig parking spaces. Located near the confluence of the Passadumkeag River; a natural takeout for paddlers coming downstream from Lincoln or Winn. Wheelchair-accessible parking lot available.

mileBadge

mileBadge

mileBadge

🐾 Pet Friendly

♿ Accessible

Surface: Hard

Passadumkeag River Access

Boat Access

1.9 mi off · Mile 178 · Rte 2

Passadumkeag

State-maintained gravel carry-in on the Passadumkeag River, a Penobscot tributary. Small watercraft only — no trailer access. Managed by Maine DIFW. Flows approximately 2 miles downstream to join the Penobscot River at Passadumkeag village.

mileBadge

mileBadge

mileBadge

🐾 Pet Friendly

♿ Accessible

♿Surface:

 Have Fun & Travel Safe! 

©2026 

All Rights Reserved.

Pine Tree Trail's "CC" LLC.

Non-Affiliation Disclaimer: Pine Tree Trail's "CC" LLC is NOT affiliated, associated or endorsed by the "Friends of the Pine Tree Trail"

   If you have any questions, comments, or would like to report an error that is on this website, please contact pinetreetrail.com by submitting the form below.

PineTreeTrail.Com, products, info, photos, and etc are brought to you by Pine Tree Trail's *CC LLC unless noted otherwise.

   If you have any questions, comments, or would like to report an error that is on this website, please contact pinetreetrail.com by submitting the form below.

PineTreeTrail.Com, products, info, photos, and etc are brought to you by Pine Tree Trail's *CC LLC unless noted otherwise.

©2026 

All Rights Reserved.

Pine Tree Trail's "CC" LLC.

Non-Affiliation Disclaimer: Pine Tree Trail's "CC" LLC is NOT affiliated, associated or endorsed by the "Friends of the Pine Tree Trail"

bottom of page