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:

Casco Bay Access

Boat Access

1.6 mi off · Mile 0 · Rte 100

Portland

City-maintained hard ramp on Casco Bay at Portland's East End waterfront. 20' wide, 180' long, 7.5% grade. Part-tide ramp with floating dock. 45 rig parking spaces, toilet facilities on site. Seasonal fee. Access to Casco Bay and the Portland Harbor islands. Launch is free. Parking ~$5/hr at Casco Bay Parking Garage, ~$15-20/day at nearby surface lots.

mileBadge

mileBadge

mileBadge

🐾 Pet Friendly

♿ Accessible

Surface: Hard

Back Cove Trail

Trails

Mile 0 · Rte 100

Portland

3.5-mile loop around Back Cove, one of Portland's busiest outdoor spaces. Flat, wide path with constant views of the cove, downtown skyline, and Casco Bay. Popular with walkers, runners, and cyclists year-round. Multi-surface: stone dust along the main loop transitions to paved sections at Tukey's Bridge and the east end.

mileBadge

mileBadge

mileBadge

🐾 Pet Friendly

♿ Accessible

Surface: Hard, Crushed Stone

Portland Freedom Trail

Landmarks

0.9 mi off · Mile 0 · Rte 100

Portland

Self-guided 2-mile walking tour of 13 Underground Railroad sites. Granite markers with bronze plates by artist Daniel Minter. Free.

mileBadge

mileBadge

mileBadge

🐾 Pet Friendly

♿ Accessible

Surface: Hard

Fore River Sanctuary - Jewell Falls

Trails

1.8 mi off · Mile 1 · Rte 100

Portland

Portland Trails-maintained urban nature sanctuary in the city's West End. Features Jewell Falls, the only natural waterfall within Portland city limits. Wooded trails through 85 acres of mixed forest, brooks, and wetlands. Connects to the Portland trail network. Accessible main trail (crushed stone) leads ~0.5 miles along the former canal towpath; side loops to Jewell Falls and marshes are natural surface with roots, rocks, and a stone staircase.

mileBadge

mileBadge

mileBadge

🐾 Pet Friendly

♿ Accessible

Surface: Crushed Stone

Mayor Baxter Woods

Trails

Mile 1 · Rte 100

Portland

City-maintained 32-acre urban woodland park named for Mayor James Phinney Baxter. Quiet wooded trails, bird-watching, and nature walks close to downtown Portland. Accessible 8-foot wide stone dust main trail connects Stevens and Forest Ave; secondary forest loops contain frequent large tree roots and uneven terrain not recommended for mobility devices.

mileBadge

mileBadge

mileBadge

🐾 Pet Friendly

♿ Accessible

Surface: Crushed Stone

Blackstrap Hill Preserve

Trails

0.6 mi off · Mile 10 · Rte 100

Falmouth

Nature preserve with over 8 miles of single-track and double-track trails. Popular for mountain biking, hiking, and trail running. Mix of wooded singletrack and open forest road.

mileBadge

mileBadge

mileBadge

🐾 Pet Friendly

♿ Accessible

♿Surface:

Thayer Brook Preserve

Trails

2.0 mi off · Mile 16 · Rte 100

Gray

Town-maintained forest preserve with multi-use trails suitable for hiking and mountain biking. Quiet wooded loops through mixed forest with moderate terrain. Separate trailhead from Libby Hill, offering complementary riding and walking.

mileBadge

mileBadge

mileBadge

🐾 Pet Friendly

♿ Accessible

♿Surface:

Libby Hill Forest Trails

Trails

1.3 mi off · Mile 17 · Rte 100

Gray

Town-maintained forest trails featuring a mountain biking network through mixed woodland. Signed trail system with a mix of beginner-friendly loops and more technical routes. Small parking area at the trailhead.

mileBadge

mileBadge

mileBadge

🐾 Pet Friendly

♿ Accessible

♿Surface:

Crystal Lake Access

Boat Access

2.1 mi off · Mile 18 · Rte 100

Gray

Town-maintained hard ramp on Crystal Lake. 12' wide, 81' long, 11% grade. Freshwater access to a small recreational lake in southern Gray.

mileBadge

mileBadge

mileBadge

🐾 Pet Friendly

♿ Accessible

Surface: Hard

Mount Apatite Park

Trails

3.2 mi off · Mile 30 · Rte 100

Auburn

Auburn city park on the site of former feldspar and mica mining operations. Extensive multi-use trail system for mountain biking, hiking, and horseback riding. Historic mine sites throughout the park add interest.

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