PageSourceSearch

https://tailorly.co/support/search.js

js tailorly.co collected 2026-09-24 14:37:02 UTC 13,732 bytes, 223 lines download raw bytes

1// search.js - Enhanced comprehensive search functionality for support pages
2
3// This object contains searchable content from all support pages
4// Format: { 'page-url.html': { title: 'Page Title', description: 'Page description', content: 'Searchable content...' } }
5const searchIndex = {
6    'index.html': {
7        title: 'Support Center',
8        description: 'Find answers, guides, and resources to help you get the most out of Tailorly',
9        content: 'Find answers, guides, and resources to help you get the most out of Tailorly. Browse our most frequently accessed guides and tutorials. Getting Started Guide, How to Save Your Resume, Extracting Job Descriptions, Troubleshooting, ATS Optimization Tips, Contact Support.'
10    },
11    'how-to-use.html': {
12        title: 'How to Use Tailorly',
13        description: 'A comprehensive guide to getting started and maximizing your results',
14        content: 'A comprehensive guide to getting started and maximizing your results. Tailorly is designed to be intuitive and easy to use, helping you optimize your resume for any job application in just seconds. This guide will walk you through the entire process from installation to applying with your tailored resume. Install the Browser Extension, Create Your Account, Upload Your Base Resume, Tailor Your Resume for a Job, Review and Download Your Tailored Resume, ATS Compatibility Score, Keyword Optimization, Cover Letter Generation, Pro Feature, Troubleshooting Common Issues.'
15    },
16    'save-resume.html': {
17        title: 'How to Save Your Resume',
18        description: 'Learn how to save, manage, and organize multiple versions of your tailored resumes',
19        content: 'Learn how to save, manage, and organize multiple versions of your tailored resumes. This guide covers saving your resume to your account, downloading different file formats, organizing your saved resumes, and accessing your resume history. Tailorly makes it easy to keep track of all your tailored resumes for different job applications. Save to Your Tailorly Account, Download Your Resume in Different Formats, Managing Your Saved Resumes, Accessing Your Resume Library, Organizing Your Resumes, Resume Version History, Sharing Your Resume, Creating Shareable Links, Backup and Recovery.'
20    },
21    'extract-job-description.html': {
22        title: 'Extracting Job Descriptions',
23        description: '3 ways to automatically extract job descriptions for our extension from any job site',
24        content: '3 ways to automatically extract job descriptions for our extension from any job site. Learn how to use the automatic extraction feature, manual copy-paste method, and URL sharing. This guide helps you efficiently capture job descriptions from LinkedIn, Indeed, Glassdoor, and company career pages to optimize your resume with Tailorly. Job Site Compatibility, Automatic Extraction, Manual Copy-Paste, URL Sharing Method, Troubleshooting Extraction Issues, Job Description Not Detected, Extracted Description Is Incomplete, Extraction Works But Analysis Fails, Extracting from Unusual Sources, PDF Job Descriptions, Email Job Descriptions, Protected Job Boards.'
25    },
26    'troubleshooting.html': {
27        title: 'Troubleshooting',
28        description: 'Solutions to common issues and problems you might encounter while using Tailorly',
29        content: 'Solutions to common issues and problems you might encounter while using Tailorly. This guide covers installation problems, resume parsing errors, job description detection issues, account access problems, and subscription management. Find quick fixes and step-by-step solutions to get back on track with your job applications. Installation Issues, Can\'t Install the Browser Extension, Extension Installed But Not Working, Resume Parsing Issues, Resume Not Parsing Correctly, Job Description Issues, Job Description Not Detected, Account and Subscription Issues, Can\'t Log In to My Account, Subscription Issues, Performance Issues, Resume Optimization Is Slow.'
30    },
31    'cancellationandrefunds.html': {
32        title: 'Cancellation and Refunds',
33        description: 'Understand Tailorly’s cancellation and refunds policy, outage credits, and how to request help.',
34        content: 'We do not offer cancellations or refunds mid-billing period. Try the free plan first. In certain verified cases such as service outages or confirmed extension malfunctions that prevent core use, we may provide remedies like subscription extensions or additional credits. This policy covers exceptions, what is not covered, and how to request help. Eligible situations: Verified service outage, Extension not functioning as intended after troubleshooting. Remedies: add credits, extend subscription. No refunds for change of mind or partial periods. Contact support with browser, OS, reproduction steps, screenshots, timestamps.'
35    },
36    'products.html': {
37        title: 'Products (Shipping and Access)',
38        description: 'Tailorly is a digital, subscription-based Chrome extension. No physical shipping. Access continues while subscribed.',
39        content: 'Tailorly is an online product and Chrome extension. No physical items are shipped. Access begins after account creation and continues while your subscription is active. Free plan available to try before upgrading. For refunds, credits, or outage remedies, see 
39Cancellation and Refunds. Getting started: install extension, create account, use free plan or upgrade.'
40    },
41    'ats-optimization.html': {
42        title: 'ATS Optimization Tips',
43        description: 'Learn how to maximize your resume\'s compatibility with Applicant Tracking Systems',
44        content: 'Learn how to maximize your resume\'s compatibility with Applicant Tracking Systems. This guide explains how ATS systems work, key formatting guidelines, optimal keyword usage, section organization, and how to test your resume against common ATS platforms. Follow these tips to ensure your resume passes through ATS filters and reaches human recruiters. Understanding ATS Systems, ATS Compatibility Score, Key Formatting Guidelines for ATS, Keyword Optimization Strategies, Identify Relevant Keywords, Use Keywords Naturally, Include Both Acronyms and Full Terms, Create a Skills Section, Resume Section Organization, Contact Information, Professional Summary/Objective, Work Experience, Education, Skills, Additional Sections, Testing Your Resume Against ATS, Common ATS Myths Debunked, Final Tips for ATS Success.'
45    },
46    'shippingpolicy.html': {
47        title: 'Shipping and Product Policies',
48        description: 'Tailorly is a digital, subscription-based Chrome extension. No physical shipping. Access continues while subscribed.',
49        content: 'Tailorly is an online product and Chrome extension. No physical items are shipped. Access begins after account creation and continues while your subscription is active. Free plan available to try before upgrading. For refunds, credits, or outage remedies, see Cancellation and Refunds. Getting started: install extension, create account, use free plan or upgrade.'
50    }
51};
52
53// Function to normalize text for searching (remove extra spaces, lowercase)
54function normalizeText(text) {
55    return text.toLowerCase().replace(/\s+/g, ' ').trim();
56}
57
58// Function to perform search across all pages
59function performSearch(query) {
60    const normalizedQuery = normalizeText(query);
61    
62    // If search is empty, return empty results
63    if (normalizedQuery === '') {
64        return [];
65    }
66    
67    const results = [];
68    
69    // Search through the index
70    for (const [url, pageData] of Object.entries(searchIndex)) {
71        const normalizedTitle = normalizeText(pageData.title);
72        const normalizedDescription = normalizeText(pageData.description);
73        const normalizedContent = normalizeText(pageData.content);
74        
75        // Check if query appears in title, description or content
76        if (normalizedTitle.includes(normalizedQuery) || 
77            normalizedDescription.includes(normalizedQuery) || 
78            normalizedContent.includes(normalizedQuery)) {
79            
80            // Calculate relevance score (higher for title matches, then description, then content)
81            let score = 0;
82            let matchType = '';
83            let snippet = '';
84            
85            // Title matches get highest score
86            if (normalizedTitle.includes(normalizedQuery)) {
87                score += 100;
88                matchType = 'title';
89                // Bonus points for exact title match
90                if (normalizedTitle === normalizedQuery) {
91                    score += 50;
92                }
93                snippet = pageData.description; // Use description as snippet for title matches
94            }
95            
96            // Description matches get medium score
97            if (normalizedDescription.includes(normalizedQuery)) {
98                score += 75;
99                if (!matchType) {
100                    matchType = 'description';
101                    snippet = pageData.description;
102                }
103            }
104            
105            // Content matches get lowest score
106            if (normalizedContent.includes(normalizedQuery)) {
107                score += 50;
108                
109                if (!matchType) {
110                    matchType = 'content';
111                    
112                    // Find the position of the match to extract a snippet
113                    const matchPosition = normalizedContent.indexOf(normalizedQuery);
114                    
115                    // Create a snippet around the match
116                    const snippetStart = Math.max(0, matchPosition - 50);
117                    const snippetEnd = Math.min(normalizedContent.length, matchPosition + normalizedQuery.length + 50);
118                    snippet = normalizedContent.substring(snippetStart, snippetEnd);
119                    
120                    // Add ellipsis if needed
121                    if (snippetStart > 0) {
122                        snippet = '...' + snippet;
123                    }
124                    if (snippetEnd < normalizedContent.length) {
125                        snippet += '...';
126                    }
127                }
128            }
129            
130            // Add result with snippet and score
131            results.push({
132                url,
133                title: pageData.title,
134                snippet: snippet || normalizedContent.substring(0, 100) + '...',
135                score,
136                matchType
137            });
138        }
139    }
140    
141    // Sort results by relevance score (highest first)
142    results.sort((a, b) => b.score - a.score);
143    
144    return results;
145}
146
147// Function to display search results
148function displaySearchResults(results, container) {
149    container.innerHTML = '';
150    
151    if (results.length === 0) {
152        container.innerHTML = `
153            <div class="search-no-results">
154                <p>No results found. Please try a different search term.</p>
155            </div>
156        `;
157        return;
158    }
159    
160    results.forEach(result => {
161        const resultElement = document.createElement('div');
162        resultElement.className = 'search-result';
163        
164        // Create badge for match type
165        let badgeHtml = '';
166        if (result.matchType === 'title') {
167            badgeHtml = '<span class="match-badge title-match">Title Match</span>';
168        } else if (result.matchType === 'description') {
169            badgeHtml = '<span class="match-badge desc-match">Description Match</span>';
170        } else {
171            badgeHtml = '<span class="match-badge content-match">Content Match</span>';
172        }
173        
174        resultElement.innerHTML = `
175            <h3>
176                <a href="${result.url}">${result.title}</a>
177                ${badgeHtml}
178            </h3>
179            <p>${result.snippet}</p>
180            <a href="${result.url}" class="result-link">Read more</a>
181        `;
182        
183        container.appendChild(resultElement);
184    });
185}
186
187// Initialize search when DOM is loaded
188document.addEventListener('DOMContentLoaded', function() {
189    const searchInput = document.getElementById('search-input');
190    const searchResults = document.getElementById('search-results');
191    const searchForm = document.getElementById('search-form');
192    
193    if (searchForm) {
194        searchForm.addEventListener('submit', function(e) {
195            e.preventDefault();
196            const query = searchInput.value;
197            const results = performSearch(query);
198            displaySearchResults(results, searchResults);
199        });
200    }
201    
202    // Add live search functionality
203    if (searchInput) {
204        searchInput.addEventListener('input', function() {
205            const query = this.value;
206            if (query.length >= 2) { // Only search for queries with 2+ characters
207                const results = performSearch(query);
208                displaySearchResults(results, searchResults);
209            } else if (query.length === 0) {
210                searchResults.innerHTML = ''; // Clear results when search is empty
211            }
212        });
213    }
214    
215    // Check for URL parameters to handle searches from other pages
216    const urlParams = new URLSearchParams(window.location.search);
217    const queryParam = urlParams.get('q');
218    if (queryParam && searchInput && searchResults) {
219        searchInput.value = queryParam;
220        const results = performSearch(queryParam);
221        displaySearchResults(results, searchResults);
222    }
223});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.