# thinkrank/1.0.0/src/admin/components/common/TitlePreview.js

ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console &amp; Local SEO, version 1.0.0. 230 lines.

- Page: https://pluginprobe.com/plugins/thinkrank/1.0.0/code/src/admin/components/common/TitlePreview.js
- Raw: https://pluginprobe.com/plugins/thinkrank/1.0.0/raw/src/admin/components/common/TitlePreview.js
- Modified: 2025-08-10T07:57:44+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/thinkrank/1.0.0/code/src/admin/components/common/TitlePreview.js#L10-L20`.

```javascript
/**
 * Title Preview Component
 * 
 * Live preview of title formats with real-time updates
 * 
 * @package ThinkRank
 * @since 1.0.0
 */

import { useState, useEffect } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { 
    Card,
    CardBody,
    CardHeader,
    __experimentalSpacer as Spacer
} from '@wordpress/components';

/**
 * Title Preview Component
 */
const TitlePreview = ({ 
    titleFormats, 
    separator, 
    siteInfo,
    disabled = false 
}) => {
    const [previews, setPreviews] = useState({});

    /**
     * Get separator character
     */
    const getSeparatorChar = (separatorType) => {
        const separators = {
            'pipe': '|',
            'dash': '-',
            'double_right': '»',
            'single_right': '›',
            'bullet': '•'
        };
        return separators[separatorType] || '|';
    };

    /**
     * Replace template variables with sample data
     */
    const replaceVariables = (template, pageType) => {
        const sampleData = {
            '%site_title%': siteInfo.site_name || 'Your Site Name',
            '%site_name%': siteInfo.site_name || 'Your Site Name',
            '%site_description%': siteInfo.site_description || 'Your site description',
            '%tagline%': siteInfo.tagline || 'Your site tagline',
            '%post_title%': 'Sample Blog Post Title',
            '%page_title%': 'Sample Page Title',
            '%category_title%': 'Sample Category',
            '%tag_title%': 'Sample Tag',
            '%author_name%': 'John Doe',
            '%search_term%': 'sample search',
            '%archive_title%': 'Sample Archive'
        };

        let result = template;
        Object.keys(sampleData).forEach(variable => {
            result = result.replace(new RegExp(variable.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'), sampleData[variable]);
        });

        return result;
    };

    /**
     * Generate title preview
     */
    const generatePreview = (template, pageType) => {
        if (!template) return '';

        const separatorChar = ` ${getSeparatorChar(separator)} `;
        let preview = replaceVariables(template, pageType);
        
        // Replace separator placeholders
        preview = preview.replace(/\s*\|\s*/g, separatorChar);
        
        return preview;
    };

    /**
     * Update previews when formats or separator change
     */
    useEffect(() => {
        const newPreviews = {};
        
        Object.keys(titleFormats).forEach(pageType => {
            newPreviews[pageType] = generatePreview(titleFormats[pageType], pageType);
        });
        
        setPreviews(newPreviews);
    }, [titleFormats, separator, siteInfo]);

    /**
     * Get page type display name
     */
    const getPageTypeLabel = (pageType) => {
        const labels = {
            'homepage_title': __('Homepage', 'thinkrank'),
            'post_title': __('Blog Post', 'thinkrank'),
            'page_title': __('Page', 'thinkrank'),
            'category_title': __('Category', 'thinkrank'),
            'tag_title': __('Tag', 'thinkrank'),
            'author_title': __('Author', 'thinkrank'),
            'search_title': __('Search Results', 'thinkrank'),
            'archive_title': __('Archive', 'thinkrank')
        };
        return labels[pageType] || pageType;
    };

    /**
     * Get title length and status
     */
    const getTitleStatus = (title) => {
        const length = title.length;
        let status = 'good';
        let message = '';

        if (length < 30) {
            status = 'warning';
            message = __('Too short - consider adding more descriptive text', 'thinkrank');
        } else if (length > 60) {
            status = 'warning';
            message = __('Too long - may be truncated in search results', 'thinkrank');
        } else {
            status = 'good';
            message = __('Good length for SEO', 'thinkrank');
        }

        return { length, status, message };
    };

    if (disabled) {
        return (
            <Card size="small">
                <CardBody>
                    <p style={{ color: '#757575', fontStyle: 'italic' }}>
                        {__('Title preview is disabled. Enable site identity to see live previews.', 'thinkrank')}
                    </p>
                </CardBody>
            </Card>
        );
    }

    return (
        <Card size="small">
            <CardHeader>
                <h4>{__('Live Title Preview', 'thinkrank')}</h4>
                <p style={{ fontSize: '14px', color: '#757575', margin: '4px 0 0 0' }}>
                    {__('See how your titles will appear with current settings', 'thinkrank')}
                </p>
            </CardHeader>
            <CardBody>
                <div className="title-preview-list">
                    {Object.keys(previews).map(pageType => {
                        const preview = previews[pageType];
                        const titleStatus = getTitleStatus(preview);
                        
                        return (
                            <div key={pageType} className="title-preview-item" style={{ marginBottom: '16px' }}>
                                <div style={{ 
                                    display: 'flex', 
                                    justifyContent: 'space-between', 
                                    alignItems: 'center',
                                    marginBottom: '4px'
                                }}>
                                    <strong>{getPageTypeLabel(pageType)}</strong>
                                    <span style={{ 
                                        fontSize: '12px',
                                        color: titleStatus.status === 'good' ? '#00a32a' : '#dba617'
                                    }}>
                                        {titleStatus.length} chars
                                    </span>
                                </div>
                                
                                <div style={{ 
                                    padding: '8px 12px',
                                    backgroundColor: '#f6f7f7',
                                    border: '1px solid #ddd',
                                    borderRadius: '4px',
                                    fontFamily: 'Arial, sans-serif',
                                    fontSize: '18px',
                                    color: '#1a0dab',
                                    lineHeight: '1.3'
                                }}>
                                    {preview || __('No title format set', 'thinkrank')}
                                </div>
                                
                                {titleStatus.message && (
                                    <p style={{ 
                                        fontSize: '12px',
                                        color: titleStatus.status === 'good' ? '#00a32a' : '#dba617',
                                        margin: '4px 0 0 0'
                                    }}>
                                        {titleStatus.message}
                                    </p>
                                )}
                            </div>
                        );
                    })}
                </div>
                
                <Spacer marginY={3} />
                
                <div style={{ 
                    padding: '12px',
                    backgroundColor: '#e7f3ff',
                    border: '1px solid #72aee6',
                    borderRadius: '4px',
                    fontSize: '13px'
                }}>
                    <strong>{__('SEO Tips:', 'thinkrank')}</strong>
                    <ul style={{ margin: '8px 0 0 0', paddingLeft: '20px' }}>
                        <li>{__('Keep titles between 30-60 characters for optimal SEO', 'thinkrank')}</li>
                        <li>{__('Include your target keyword near the beginning', 'thinkrank')}</li>
                        <li>{__('Make titles descriptive and compelling for users', 'thinkrank')}</li>
                        <li>{__('Use consistent separators across your site', 'thinkrank')}</li>
                    </ul>
                </div>
            </CardBody>
        </Card>
    );
};

export default TitlePreview;

```
