Compare commits
2 Commits
6a5721598d
...
b429b8bc5d
Author | SHA1 | Date | |
---|---|---|---|
|
b429b8bc5d | ||
|
fd0137fe74 |
134
I18N_README.md
Normal file
134
I18N_README.md
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
# Система Интернационализации (i18n) для ExamPass
|
||||||
|
|
||||||
|
## Обзор
|
||||||
|
|
||||||
|
Система интернационализации позволяет переключаться между русским и английским языками на сайте ExamPass. Система автоматически сохраняет выбранный язык в localStorage и восстанавливает его при следующем посещении.
|
||||||
|
|
||||||
|
## Структура файлов
|
||||||
|
|
||||||
|
```
|
||||||
|
src/js/
|
||||||
|
├── translations.js # Файл с переводами
|
||||||
|
├── i18n.js # Основная логика интернационализации
|
||||||
|
└── main.js # Основной JavaScript файл (обновлен)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Как это работает
|
||||||
|
|
||||||
|
### 1. Файл переводов (`translations.js`)
|
||||||
|
|
||||||
|
Содержит объект `translations` с переводами для всех поддерживаемых языков:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const translations = {
|
||||||
|
en: {
|
||||||
|
nav_about: "About",
|
||||||
|
hero_title_line1: "PASS ANY EXAM",
|
||||||
|
// ... другие переводы
|
||||||
|
},
|
||||||
|
ru: {
|
||||||
|
nav_about: "О нас",
|
||||||
|
hero_title_line1: "СДАЙ ЛЮБОЙ ЭКЗАМЕН",
|
||||||
|
// ... другие переводы
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Основная логика (`i18n.js`)
|
||||||
|
|
||||||
|
Класс `I18n` управляет:
|
||||||
|
- Переключением языков
|
||||||
|
- Сохранением выбранного языка
|
||||||
|
- Обновлением контента на странице
|
||||||
|
- Обновлением мета-тегов
|
||||||
|
|
||||||
|
### 3. HTML разметка
|
||||||
|
|
||||||
|
Элементы, которые нужно переводить, помечаются атрибутом `data-i18n`:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<a href="#about" data-i18n="nav_about">About</a>
|
||||||
|
<h1 data-i18n="hero_title_line1">PASS ANY EXAM</h1>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование
|
||||||
|
|
||||||
|
### Переключение языков
|
||||||
|
|
||||||
|
Пользователи могут переключать язык, нажимая на кнопки "EN" или "RU" в навигации:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<div class="lang-switch">
|
||||||
|
<a href="#" class="active">EN</a>
|
||||||
|
<a href="#">RU</a>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Добавление новых переводов
|
||||||
|
|
||||||
|
1. Добавьте новый ключ в объект `translations` в файле `translations.js`:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const translations = {
|
||||||
|
en: {
|
||||||
|
new_key: "English text",
|
||||||
|
// ...
|
||||||
|
},
|
||||||
|
ru: {
|
||||||
|
new_key: "Русский текст",
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Добавьте атрибут `data-i18n` к HTML элементу:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<p data-i18n="new_key">Default text</p>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Специальные случаи
|
||||||
|
|
||||||
|
#### Сложные элементы
|
||||||
|
|
||||||
|
Для элементов с HTML разметкой внутри (например, с `<strong>` тегами) используется специальная обработка в методе `translateComplexElements()`.
|
||||||
|
|
||||||
|
#### Плейсхолдеры для input полей
|
||||||
|
|
||||||
|
Для input полей перевод применяется к атрибуту `placeholder`:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<input type="text" data-i18n="form_name_placeholder" placeholder="Enter your name">
|
||||||
|
```
|
||||||
|
|
||||||
|
## Поддерживаемые элементы
|
||||||
|
|
||||||
|
Система автоматически переводит:
|
||||||
|
|
||||||
|
- Навигационные ссылки
|
||||||
|
- Заголовки секций
|
||||||
|
- Описания
|
||||||
|
- Кнопки и формы
|
||||||
|
- Footer ссылки
|
||||||
|
- Мета-теги (language, og:locale)
|
||||||
|
|
||||||
|
## Тестирование
|
||||||
|
|
||||||
|
Для тестирования системы интернационализации используйте файл `test.html`. Он содержит примеры всех типов переводимых элементов.
|
||||||
|
|
||||||
|
## Автоматическое сохранение
|
||||||
|
|
||||||
|
Выбранный язык автоматически сохраняется в localStorage браузера и восстанавливается при следующем посещении сайта.
|
||||||
|
|
||||||
|
## SEO оптимизация
|
||||||
|
|
||||||
|
Система автоматически обновляет:
|
||||||
|
- Атрибут `lang` у тега `<html>`
|
||||||
|
- Мета-тег `language`
|
||||||
|
- Open Graph тег `og:locale`
|
||||||
|
|
||||||
|
Это помогает поисковым системам правильно индексировать контент на разных языках.
|
||||||
|
|
||||||
|
## Совместимость
|
||||||
|
|
||||||
|
Система работает во всех современных браузерах и не требует дополнительных зависимостей.
|
28
robots.txt
Normal file
28
robots.txt
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
User-agent: *
|
||||||
|
Allow: /
|
||||||
|
|
||||||
|
# Sitemap
|
||||||
|
Sitemap: https://exampass.com/sitemap.xml
|
||||||
|
|
||||||
|
# Crawl-delay for respectful crawling
|
||||||
|
Crawl-delay: 1
|
||||||
|
|
||||||
|
# Allow all important pages
|
||||||
|
Allow: /index.html
|
||||||
|
Allow: /src/
|
||||||
|
Allow: /assets/
|
||||||
|
|
||||||
|
# Disallow admin or private areas (if any)
|
||||||
|
Disallow: /admin/
|
||||||
|
Disallow: /private/
|
||||||
|
Disallow: /temp/
|
||||||
|
|
||||||
|
# Allow search engines to index all content
|
||||||
|
Allow: /#about
|
||||||
|
Allow: /#methodology
|
||||||
|
Allow: /#contact
|
||||||
|
Allow: /#success
|
||||||
|
|
||||||
|
# Optimize for mobile
|
||||||
|
Allow: /mobile/
|
||||||
|
Allow: /responsive/
|
57
sitemap.xml
Normal file
57
sitemap.xml
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
|
||||||
|
xmlns:xhtml="http://www.w3.org/1999/xhtml">
|
||||||
|
|
||||||
|
<!-- Homepage -->
|
||||||
|
<url>
|
||||||
|
<loc>https://exampass.com/</loc>
|
||||||
|
<lastmod>2025-01-03</lastmod>
|
||||||
|
<changefreq>weekly</changefreq>
|
||||||
|
<priority>1.0</priority>
|
||||||
|
<xhtml:link rel="alternate" hreflang="en" href="https://exampass.com/"/>
|
||||||
|
<xhtml:link rel="alternate" hreflang="ru" href="https://exampass.com/ru/"/>
|
||||||
|
</url>
|
||||||
|
|
||||||
|
<!-- Russian version -->
|
||||||
|
<url>
|
||||||
|
<loc>https://exampass.com/ru/</loc>
|
||||||
|
<lastmod>2025-01-03</lastmod>
|
||||||
|
<changefreq>weekly</changefreq>
|
||||||
|
<priority>0.9</priority>
|
||||||
|
<xhtml:link rel="alternate" hreflang="en" href="https://exampass.com/"/>
|
||||||
|
<xhtml:link rel="alternate" hreflang="ru" href="https://exampass.com/ru/"/>
|
||||||
|
</url>
|
||||||
|
|
||||||
|
<!-- About section -->
|
||||||
|
<url>
|
||||||
|
<loc>https://exampass.com/#about</loc>
|
||||||
|
<lastmod>2025-01-03</lastmod>
|
||||||
|
<changefreq>monthly</changefreq>
|
||||||
|
<priority>0.8</priority>
|
||||||
|
</url>
|
||||||
|
|
||||||
|
<!-- Methodology section -->
|
||||||
|
<url>
|
||||||
|
<loc>https://exampass.com/#methodology</loc>
|
||||||
|
<lastmod>2025-01-03</lastmod>
|
||||||
|
<changefreq>monthly</changefreq>
|
||||||
|
<priority>0.8</priority>
|
||||||
|
</url>
|
||||||
|
|
||||||
|
<!-- Contact section -->
|
||||||
|
<url>
|
||||||
|
<loc>https://exampass.com/#contact</loc>
|
||||||
|
<lastmod>2025-01-03</lastmod>
|
||||||
|
<changefreq>monthly</changefreq>
|
||||||
|
<priority>0.7</priority>
|
||||||
|
</url>
|
||||||
|
|
||||||
|
<!-- Success stories -->
|
||||||
|
<url>
|
||||||
|
<loc>https://exampass.com/#success</loc>
|
||||||
|
<lastmod>2025-01-03</lastmod>
|
||||||
|
<changefreq>weekly</changefreq>
|
||||||
|
<priority>0.8</priority>
|
||||||
|
</url>
|
||||||
|
|
||||||
|
</urlset>
|
BIN
src/assets/logo/ExamPasss_logo_transparent_trimmed.png
Normal file
BIN
src/assets/logo/ExamPasss_logo_transparent_trimmed.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 84 KiB |
3791
src/css/style.css
3791
src/css/style.css
File diff suppressed because it is too large
Load Diff
1351
src/index.html
1351
src/index.html
File diff suppressed because it is too large
Load Diff
432
src/js/i18n.js
Normal file
432
src/js/i18n.js
Normal file
@ -0,0 +1,432 @@
|
|||||||
|
// Internationalization (i18n) System
|
||||||
|
class I18n {
|
||||||
|
constructor() {
|
||||||
|
this.currentLang = localStorage.getItem('language') || 'en';
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
this.setLanguage(this.currentLang);
|
||||||
|
this.setupLanguageSwitchers();
|
||||||
|
}
|
||||||
|
|
||||||
|
setLanguage(lang) {
|
||||||
|
try {
|
||||||
|
this.currentLang = lang;
|
||||||
|
localStorage.setItem('language', lang);
|
||||||
|
|
||||||
|
// Update HTML lang attribute
|
||||||
|
document.documentElement.lang = lang;
|
||||||
|
|
||||||
|
// Update meta tags
|
||||||
|
this.updateMetaTags(lang);
|
||||||
|
|
||||||
|
// Translate all content
|
||||||
|
this.translatePage();
|
||||||
|
|
||||||
|
// Update language switcher UI
|
||||||
|
this.updateLanguageSwitcherUI(lang);
|
||||||
|
|
||||||
|
// Update carousel cards if they exist
|
||||||
|
setTimeout(() => {
|
||||||
|
this.updateCarouselCards();
|
||||||
|
}, 100);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error setting language:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateMetaTags(lang) {
|
||||||
|
// Update meta language tag
|
||||||
|
let metaLang = document.querySelector('meta[name="language"]');
|
||||||
|
if (!metaLang) {
|
||||||
|
metaLang = document.createElement('meta');
|
||||||
|
metaLang.name = 'language';
|
||||||
|
document.head.appendChild(metaLang);
|
||||||
|
}
|
||||||
|
metaLang.content = lang === 'ru' ? 'Russian' : 'English';
|
||||||
|
|
||||||
|
// Update Open Graph locale
|
||||||
|
let ogLocale = document.querySelector('meta[property="og:locale"]');
|
||||||
|
if (!ogLocale) {
|
||||||
|
ogLocale = document.createElement('meta');
|
||||||
|
ogLocale.setAttribute('property', 'og:locale');
|
||||||
|
document.head.appendChild(ogLocale);
|
||||||
|
}
|
||||||
|
ogLocale.content = lang === 'ru' ? 'ru_RU' : 'en_US';
|
||||||
|
}
|
||||||
|
|
||||||
|
translatePage() {
|
||||||
|
const elements = document.querySelectorAll('[data-i18n]');
|
||||||
|
|
||||||
|
elements.forEach(element => {
|
||||||
|
const key = element.getAttribute('data-i18n');
|
||||||
|
const translation = this.getTranslation(key);
|
||||||
|
|
||||||
|
if (translation) {
|
||||||
|
if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') {
|
||||||
|
element.placeholder = translation;
|
||||||
|
} else {
|
||||||
|
element.textContent = translation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Special handling for complex elements
|
||||||
|
this.translateComplexElements();
|
||||||
|
}
|
||||||
|
|
||||||
|
translateComplexElements() {
|
||||||
|
// Hero section title
|
||||||
|
const heroTitleLine1 = document.querySelector('.hero-title-line1');
|
||||||
|
const heroTitleLine2 = document.querySelector('.hero-title-line2');
|
||||||
|
const heroTitleClick = document.querySelector('.hero-title-click');
|
||||||
|
|
||||||
|
if (heroTitleLine1) heroTitleLine1.textContent = this.getTranslation('hero_title_line1');
|
||||||
|
if (heroTitleLine2) heroTitleLine2.textContent = this.getTranslation('hero_title_line2');
|
||||||
|
if (heroTitleClick) heroTitleClick.textContent = this.getTranslation('hero_title_click');
|
||||||
|
|
||||||
|
// Hero description
|
||||||
|
const heroDescription = document.querySelector('.hero-description');
|
||||||
|
if (heroDescription) {
|
||||||
|
heroDescription.innerHTML = this.getTranslation('hero_description');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Navigation
|
||||||
|
const navLinks = document.querySelectorAll('.nav-links a, .mobile-nav-links a');
|
||||||
|
navLinks.forEach(link => {
|
||||||
|
const href = link.getAttribute('href');
|
||||||
|
if (href === '#about') {
|
||||||
|
link.textContent = this.getTranslation('nav_about');
|
||||||
|
} else if (href === '#methodology') {
|
||||||
|
link.textContent = this.getTranslation('nav_exams');
|
||||||
|
} else if (href === '#contact') {
|
||||||
|
link.textContent = this.getTranslation('nav_contact');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Stats section
|
||||||
|
const statsOverline = document.querySelector('.stats-overline');
|
||||||
|
const statsTitle = document.querySelector('.stats-title');
|
||||||
|
if (statsOverline) statsOverline.textContent = this.getTranslation('stats_overline');
|
||||||
|
if (statsTitle) statsTitle.textContent = this.getTranslation('stats_title');
|
||||||
|
|
||||||
|
// Stat cards
|
||||||
|
const statCards = document.querySelectorAll('.stat-card');
|
||||||
|
statCards.forEach((card, index) => {
|
||||||
|
const title = card.querySelector('.stat-title');
|
||||||
|
const description = card.querySelector('.stat-description');
|
||||||
|
|
||||||
|
if (index === 0) {
|
||||||
|
if (title) title.textContent = this.getTranslation('stat_guarantee_title');
|
||||||
|
if (description) description.textContent = this.getTranslation('stat_guarantee_desc');
|
||||||
|
} else if (index === 1) {
|
||||||
|
if (title) title.textContent = this.getTranslation('stat_years_title');
|
||||||
|
if (description) description.textContent = this.getTranslation('stat_years_desc');
|
||||||
|
} else if (index === 2) {
|
||||||
|
if (title) title.textContent = this.getTranslation('stat_students_title');
|
||||||
|
if (description) description.textContent = this.getTranslation('stat_students_desc');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Methodology section
|
||||||
|
const methodologyOverline = document.querySelector('.exam-types-overline');
|
||||||
|
const methodologyTitle = document.querySelector('.exam-types-title');
|
||||||
|
if (methodologyOverline) methodologyOverline.textContent = this.getTranslation('methodology_overline');
|
||||||
|
if (methodologyTitle) methodologyTitle.textContent = this.getTranslation('methodology_title');
|
||||||
|
|
||||||
|
// Accordion items
|
||||||
|
this.translateAccordionItems();
|
||||||
|
|
||||||
|
// About section
|
||||||
|
this.translateAboutSection();
|
||||||
|
|
||||||
|
// Success section
|
||||||
|
const successOverline = document.querySelector('.success-overline');
|
||||||
|
const successTitle = document.querySelector('.success-title');
|
||||||
|
const successSubtitle = document.querySelector('.success-subtitle');
|
||||||
|
if (successOverline) successOverline.textContent = this.getTranslation('success_overline');
|
||||||
|
if (successTitle) successTitle.textContent = this.getTranslation('success_title');
|
||||||
|
if (successSubtitle) successSubtitle.textContent = this.getTranslation('success_subtitle');
|
||||||
|
|
||||||
|
// Update testimonials in carousel
|
||||||
|
this.updateTestimonials();
|
||||||
|
|
||||||
|
// Contact section
|
||||||
|
this.translateContactSection();
|
||||||
|
|
||||||
|
// Footer
|
||||||
|
this.translateFooter();
|
||||||
|
|
||||||
|
// Breadcrumbs
|
||||||
|
const breadcrumbHome = document.querySelector('.breadcrumbs span');
|
||||||
|
if (breadcrumbHome) breadcrumbHome.textContent = this.getTranslation('breadcrumb_home');
|
||||||
|
}
|
||||||
|
|
||||||
|
translateAccordionItems() {
|
||||||
|
// GMAT/GRE
|
||||||
|
const gmatItem = document.querySelector('[data-exam="gmat"]');
|
||||||
|
if (gmatItem) {
|
||||||
|
const title = gmatItem.querySelector('h3');
|
||||||
|
const subtitle = gmatItem.querySelector('.accordion-subtitle');
|
||||||
|
const description = gmatItem.querySelector('.exam-description');
|
||||||
|
const features = gmatItem.querySelectorAll('.feature-tag');
|
||||||
|
|
||||||
|
if (title) title.textContent = this.getTranslation('gmat_title');
|
||||||
|
if (subtitle) subtitle.textContent = this.getTranslation('gmat_subtitle');
|
||||||
|
if (description) description.textContent = this.getTranslation('gmat_description');
|
||||||
|
|
||||||
|
features.forEach((feature, index) => {
|
||||||
|
const key = `gmat_feature${index + 1}`;
|
||||||
|
feature.textContent = this.getTranslation(key);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// TOEFL/IELTS
|
||||||
|
const toeflItem = document.querySelector('[data-exam="toefl"]');
|
||||||
|
if (toeflItem) {
|
||||||
|
const title = toeflItem.querySelector('h3');
|
||||||
|
const subtitle = toeflItem.querySelector('.accordion-subtitle');
|
||||||
|
const description = toeflItem.querySelector('.exam-description');
|
||||||
|
const features = toeflItem.querySelectorAll('.feature-tag');
|
||||||
|
|
||||||
|
if (title) title.textContent = this.getTranslation('toefl_title');
|
||||||
|
if (subtitle) subtitle.textContent = this.getTranslation('toefl_subtitle');
|
||||||
|
if (description) description.textContent = this.getTranslation('toefl_description');
|
||||||
|
|
||||||
|
features.forEach((feature, index) => {
|
||||||
|
const key = `toefl_feature${index + 1}`;
|
||||||
|
feature.textContent = this.getTranslation(key);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Admission
|
||||||
|
const admissionItem = document.querySelector('[data-exam="admission"]');
|
||||||
|
if (admissionItem) {
|
||||||
|
const title = admissionItem.querySelector('h3');
|
||||||
|
const subtitle = admissionItem.querySelector('.accordion-subtitle');
|
||||||
|
const description = admissionItem.querySelector('.exam-description');
|
||||||
|
const features = admissionItem.querySelectorAll('.feature-tag');
|
||||||
|
|
||||||
|
if (title) title.textContent = this.getTranslation('admission_title');
|
||||||
|
if (subtitle) subtitle.textContent = this.getTranslation('admission_subtitle');
|
||||||
|
if (description) description.textContent = this.getTranslation('admission_description');
|
||||||
|
|
||||||
|
features.forEach((feature, index) => {
|
||||||
|
const key = `admission_feature${index + 1}`;
|
||||||
|
feature.textContent = this.getTranslation(key);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// SAT/ACT
|
||||||
|
const satItem = document.querySelector('[data-exam="sat-act"]');
|
||||||
|
if (satItem) {
|
||||||
|
const title = satItem.querySelector('h3');
|
||||||
|
const subtitle = satItem.querySelector('.accordion-subtitle');
|
||||||
|
const description = satItem.querySelector('.exam-description');
|
||||||
|
const features = satItem.querySelectorAll('.feature-tag');
|
||||||
|
|
||||||
|
if (title) title.textContent = this.getTranslation('sat_title');
|
||||||
|
if (subtitle) subtitle.textContent = this.getTranslation('sat_subtitle');
|
||||||
|
if (description) description.textContent = this.getTranslation('sat_description');
|
||||||
|
|
||||||
|
features.forEach((feature, index) => {
|
||||||
|
const key = `sat_feature${index + 1}`;
|
||||||
|
feature.textContent = this.getTranslation(key);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
translateAboutSection() {
|
||||||
|
const aboutOverline = document.querySelector('.about-overline');
|
||||||
|
const aboutTitle = document.querySelector('.about-title');
|
||||||
|
const aboutGradientText = document.querySelector('.about-title .gradient-text');
|
||||||
|
const aboutLargeText = document.querySelector('.about-description .large-text');
|
||||||
|
const aboutHighlight = document.querySelector('.about-description .highlight-block p');
|
||||||
|
const aboutDescription = document.querySelector('.about-description .text-block:last-child p');
|
||||||
|
const priceLabel = document.querySelector('.price-label');
|
||||||
|
const priceNote = document.querySelector('.price-note');
|
||||||
|
|
||||||
|
if (aboutOverline) aboutOverline.textContent = this.getTranslation('about_overline');
|
||||||
|
if (aboutTitle) {
|
||||||
|
const titleText = this.getTranslation('about_title');
|
||||||
|
aboutTitle.innerHTML = `${titleText} <span class="gradient-text">${this.getTranslation('about_gradient_text')}</span>`;
|
||||||
|
}
|
||||||
|
if (aboutLargeText) aboutLargeText.textContent = this.getTranslation('about_large_text');
|
||||||
|
if (aboutHighlight) aboutHighlight.textContent = this.getTranslation('about_highlight');
|
||||||
|
if (aboutDescription) aboutDescription.textContent = this.getTranslation('about_description');
|
||||||
|
if (priceLabel) priceLabel.textContent = this.getTranslation('price_label');
|
||||||
|
if (priceNote) priceNote.textContent = this.getTranslation('price_note');
|
||||||
|
}
|
||||||
|
|
||||||
|
translateContactSection() {
|
||||||
|
const contactHeading = document.querySelector('.contact-heading');
|
||||||
|
const contactSubheading = document.querySelector('.contact-subheading');
|
||||||
|
const contactHighlight = document.querySelector('.contact-subheading .highlight-text');
|
||||||
|
const contactTelegram = document.querySelector('.contact-method-btn[href*="telegram"]');
|
||||||
|
const contactWhatsapp = document.querySelector('.contact-method-btn[href*="whatsapp"]');
|
||||||
|
const contactInstagram = document.querySelector('.contact-method-btn[href*="instagram"]');
|
||||||
|
const formHeaderTitle = document.querySelector('.form-header h3');
|
||||||
|
const formHeaderSubtitle = document.querySelector('.form-header p');
|
||||||
|
const formNameLabel = document.querySelector('label[for="firstName"]');
|
||||||
|
const formNameInput = document.querySelector('#firstName');
|
||||||
|
const formPhoneLabel = document.querySelector('label[for="phone"]');
|
||||||
|
const formPhoneInput = document.querySelector('#phone');
|
||||||
|
const formSubmit = document.querySelector('.submit-btn span');
|
||||||
|
|
||||||
|
if (contactHeading) {
|
||||||
|
contactHeading.innerHTML = `<span>${this.getTranslation('contact_heading_line1')}</span><span>${this.getTranslation('contact_heading_line2')}</span>`;
|
||||||
|
}
|
||||||
|
if (contactSubheading) {
|
||||||
|
contactSubheading.innerHTML = `${this.getTranslation('contact_subheading')} <span class="highlight-text">${this.getTranslation('contact_highlight')}</span>`;
|
||||||
|
}
|
||||||
|
if (contactTelegram) contactTelegram.textContent = this.getTranslation('contact_telegram');
|
||||||
|
if (contactWhatsapp) contactWhatsapp.textContent = this.getTranslation('contact_whatsapp');
|
||||||
|
if (contactInstagram) contactInstagram.textContent = this.getTranslation('contact_instagram');
|
||||||
|
if (formHeaderTitle) formHeaderTitle.textContent = this.getTranslation('form_header_title');
|
||||||
|
if (formHeaderSubtitle) formHeaderSubtitle.textContent = this.getTranslation('form_header_subtitle');
|
||||||
|
if (formNameLabel) formNameLabel.textContent = this.getTranslation('form_name_label');
|
||||||
|
if (formNameInput) formNameInput.placeholder = this.getTranslation('form_name_placeholder');
|
||||||
|
if (formPhoneLabel) formPhoneLabel.textContent = this.getTranslation('form_phone_label');
|
||||||
|
if (formPhoneInput) formPhoneInput.placeholder = this.getTranslation('form_phone_placeholder');
|
||||||
|
if (formSubmit) formSubmit.textContent = this.getTranslation('form_submit');
|
||||||
|
}
|
||||||
|
|
||||||
|
translateFooter() {
|
||||||
|
const footerDescription = document.querySelector('.footer-info p');
|
||||||
|
const footerExamTypes = document.querySelector('.footer-links h4:first-of-type');
|
||||||
|
const footerServices = document.querySelector('.footer-links h4:nth-of-type(2)');
|
||||||
|
const footerContact = document.querySelector('.footer-links h4:last-of-type');
|
||||||
|
const footerCopyright = document.querySelector('.footer-bottom p');
|
||||||
|
|
||||||
|
if (footerDescription) footerDescription.textContent = this.getTranslation('footer_description');
|
||||||
|
if (footerExamTypes) footerExamTypes.textContent = this.getTranslation('footer_exam_types');
|
||||||
|
if (footerServices) footerServices.textContent = this.getTranslation('footer_services');
|
||||||
|
if (footerContact) footerContact.textContent = this.getTranslation('footer_contact');
|
||||||
|
if (footerCopyright) footerCopyright.textContent = this.getTranslation('footer_copyright');
|
||||||
|
|
||||||
|
// Footer links
|
||||||
|
const footerLinks = document.querySelectorAll('.footer-links a');
|
||||||
|
footerLinks.forEach(link => {
|
||||||
|
const href = link.getAttribute('href');
|
||||||
|
if (href === '#about') {
|
||||||
|
link.textContent = this.getTranslation('footer_our_method');
|
||||||
|
} else if (href === '#success') {
|
||||||
|
link.textContent = this.getTranslation('footer_success_stories');
|
||||||
|
} else if (href === '#contact') {
|
||||||
|
link.textContent = this.getTranslation('footer_free_consultation');
|
||||||
|
} else if (href === '#contact' && link.textContent.includes('Started')) {
|
||||||
|
link.textContent = this.getTranslation('footer_get_started');
|
||||||
|
} else if (href.includes('telegram')) {
|
||||||
|
link.textContent = this.getTranslation('footer_telegram_support');
|
||||||
|
} else if (href.includes('mailto')) {
|
||||||
|
link.textContent = this.getTranslation('footer_email_us');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getTranslation(key) {
|
||||||
|
return translations[this.currentLang]?.[key] || key;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateTestimonials() {
|
||||||
|
// Update testimonials in the carousel if it exists
|
||||||
|
const testimonials = document.querySelectorAll('.testimonial');
|
||||||
|
if (testimonials.length > 0) {
|
||||||
|
// Only translate if current language is Russian
|
||||||
|
if (this.currentLang === 'ru') {
|
||||||
|
const testimonialKeys = ['testimonial_alex', 'testimonial_maria', 'testimonial_david', 'testimonial_sarah'];
|
||||||
|
|
||||||
|
testimonials.forEach((testimonial, index) => {
|
||||||
|
if (index < testimonialKeys.length) {
|
||||||
|
const translation = this.getTranslation(testimonialKeys[index]);
|
||||||
|
if (translation && translation !== testimonialKeys[index]) {
|
||||||
|
testimonial.textContent = '"' + translation + '"';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update carousel cards if they exist
|
||||||
|
this.updateCarouselCards();
|
||||||
|
}
|
||||||
|
|
||||||
|
updateCarouselCards() {
|
||||||
|
// Check if carousel exists and update current card
|
||||||
|
if (typeof window.currentCard !== 'undefined' && typeof window.cards !== 'undefined' && window.cards.length > 0) {
|
||||||
|
const currentCardData = window.cards[window.currentCard];
|
||||||
|
if (currentCardData) {
|
||||||
|
let testimonialText = currentCardData.testimonial;
|
||||||
|
|
||||||
|
// Only translate if current language is Russian
|
||||||
|
if (this.currentLang === 'ru') {
|
||||||
|
const testimonialKeys = ['testimonial_alex', 'testimonial_maria', 'testimonial_david', 'testimonial_sarah'];
|
||||||
|
const translation = this.getTranslation(testimonialKeys[window.currentCard]);
|
||||||
|
|
||||||
|
// Use translation if available and not equal to key
|
||||||
|
if (translation && translation !== testimonialKeys[window.currentCard]) {
|
||||||
|
testimonialText = translation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update testimonial in both front and back cards
|
||||||
|
const frontTestimonial = document.querySelector('.card-face.front .testimonial');
|
||||||
|
const backTestimonial = document.querySelector('.card-face.back .testimonial');
|
||||||
|
|
||||||
|
if (frontTestimonial) {
|
||||||
|
frontTestimonial.textContent = '"' + testimonialText + '"';
|
||||||
|
}
|
||||||
|
if (backTestimonial) {
|
||||||
|
backTestimonial.textContent = '"' + testimonialText + '"';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setupLanguageSwitchers() {
|
||||||
|
const languageSwitchers = document.querySelectorAll('.lang-switch, .mobile-lang-switch');
|
||||||
|
|
||||||
|
languageSwitchers.forEach(switcher => {
|
||||||
|
const links = switcher.querySelectorAll('a');
|
||||||
|
|
||||||
|
links.forEach(link => {
|
||||||
|
// Remove existing event listeners to prevent duplicates
|
||||||
|
link.removeEventListener('click', this.handleLanguageSwitch);
|
||||||
|
|
||||||
|
// Add new event listener
|
||||||
|
link.addEventListener('click', this.handleLanguageSwitch.bind(this));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
handleLanguageSwitch(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
const lang = e.target.textContent.toLowerCase();
|
||||||
|
if (lang === 'en' || lang === 'ru') {
|
||||||
|
this.setLanguage(lang);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateLanguageSwitcherUI(lang) {
|
||||||
|
const languageSwitchers = document.querySelectorAll('.lang-switch, .mobile-lang-switch');
|
||||||
|
|
||||||
|
languageSwitchers.forEach(switcher => {
|
||||||
|
const links = switcher.querySelectorAll('a');
|
||||||
|
|
||||||
|
links.forEach(link => {
|
||||||
|
link.classList.remove('active');
|
||||||
|
if (link.textContent.toLowerCase() === lang) {
|
||||||
|
link.classList.add('active');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize i18n when DOM is loaded
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
window.i18n = new I18n();
|
||||||
|
});
|
1220
src/js/main.js
1220
src/js/main.js
File diff suppressed because it is too large
Load Diff
223
src/js/translations.js
Normal file
223
src/js/translations.js
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
const translations = {
|
||||||
|
en: {
|
||||||
|
// Navigation
|
||||||
|
nav_about: "About",
|
||||||
|
nav_exams: "Exams",
|
||||||
|
nav_contact: "Contact",
|
||||||
|
|
||||||
|
// Hero Section
|
||||||
|
hero_title_line1: "PASS ANY EXAM",
|
||||||
|
hero_title_line2: "IN ONE",
|
||||||
|
hero_title_click: "CLICK",
|
||||||
|
hero_description: "Guaranteed admission to top-tier universities worldwide. Our revolutionary methods ensure 100% success rate - no courses, just guaranteed results to Harvard, Oxford, Cambridge, and Stanford.",
|
||||||
|
|
||||||
|
// Stats Section
|
||||||
|
stats_overline: "Our Success",
|
||||||
|
stats_title: "Our Achievements",
|
||||||
|
stat_guarantee_title: "100% Guarantee",
|
||||||
|
stat_guarantee_desc: "Success rate with our revolutionary methods",
|
||||||
|
stat_years_title: "6 Years",
|
||||||
|
stat_years_desc: "Of guaranteed university admissions",
|
||||||
|
stat_students_title: "1000+ Students",
|
||||||
|
stat_students_desc: "Successfully admitted to top universities worldwide",
|
||||||
|
|
||||||
|
// Methodology Section
|
||||||
|
methodology_overline: "What We Guarantee",
|
||||||
|
methodology_title: "Revolutionary Methods",
|
||||||
|
|
||||||
|
// GMAT/GRE
|
||||||
|
gmat_title: "GMAT Focus Edition & GRE",
|
||||||
|
gmat_subtitle: "Business & Graduate Schools",
|
||||||
|
gmat_description: "Revolutionary analytical methods for elite business schools and universities. Our guaranteed approach ensures admission to Master's programs, MBA, Executive MBA, and PhD at top institutions.",
|
||||||
|
gmat_feature1: "Quantitative Reasoning",
|
||||||
|
gmat_feature2: "Verbal Reasoning",
|
||||||
|
gmat_feature3: "Analytical Writing",
|
||||||
|
gmat_feature4: "Integrated Reasoning",
|
||||||
|
|
||||||
|
// TOEFL/IELTS
|
||||||
|
toefl_title: "TOEFL iBT & IELTS Indicator",
|
||||||
|
toefl_subtitle: "English Proficiency",
|
||||||
|
toefl_description: "Exams which evaluate your level of English, they must be passed for applying for any international studying programs, these exams are the most popular among international exams",
|
||||||
|
toefl_feature1: "Reading Comprehension",
|
||||||
|
toefl_feature2: "Listening Skills",
|
||||||
|
toefl_feature3: "Speaking Practice",
|
||||||
|
toefl_feature4: "Writing Tasks",
|
||||||
|
|
||||||
|
// Admission
|
||||||
|
admission_title: "Admission Abroad",
|
||||||
|
admission_subtitle: "University Applications",
|
||||||
|
admission_description: "TOP World's best universities and business schools guaranteed admission: Harvard, Stanford, Oxford, LBS, Cambridge; Master of Business Administration programs, Executive MBA, Master's degree",
|
||||||
|
admission_feature1: "Harvard University",
|
||||||
|
admission_feature2: "Stanford University",
|
||||||
|
admission_feature3: "Oxford University",
|
||||||
|
admission_feature4: "Cambridge University",
|
||||||
|
|
||||||
|
// SAT/ACT
|
||||||
|
sat_title: "SAT & ACT",
|
||||||
|
sat_subtitle: "Undergraduate Admissions",
|
||||||
|
sat_description: "Standardized tests required for undergraduate admissions to US colleges and universities. These exams evaluate critical thinking, problem-solving, and academic readiness for higher education.",
|
||||||
|
sat_feature1: "Math & English",
|
||||||
|
sat_feature2: "Critical Reading",
|
||||||
|
sat_feature3: "Essay Writing",
|
||||||
|
sat_feature4: "Science Reasoning",
|
||||||
|
|
||||||
|
// About Section
|
||||||
|
about_overline: "About Us",
|
||||||
|
about_title: "We're",
|
||||||
|
about_gradient_text: "SnapPass",
|
||||||
|
about_large_text: "A team of experts ready to transform the way you prepare for exams.",
|
||||||
|
about_highlight: "Forget sleepless nights and endless courses — we do things differently.",
|
||||||
|
about_description: "With us, everything is easy and straightforward: you'll feel confident after the very first step, and within days you'll be holding an official acceptance letter from a top‑tier university in your hands.",
|
||||||
|
price_label: "Average Total Price",
|
||||||
|
price_amount: "15,000",
|
||||||
|
price_note: "The only company no one can compete with, unique and exclusive",
|
||||||
|
|
||||||
|
// Success Section
|
||||||
|
success_overline: "Success Stories",
|
||||||
|
success_title: "Real Results",
|
||||||
|
success_subtitle: "Students who transformed their futures with our help",
|
||||||
|
|
||||||
|
// Contact Section
|
||||||
|
contact_heading_line1: "READY TO",
|
||||||
|
contact_heading_line2: "SUCCEED?",
|
||||||
|
contact_subheading: "Transform your future today. Join thousands who achieved their dreams with our expert guidance.",
|
||||||
|
contact_highlight: "Your success story starts here.",
|
||||||
|
contact_telegram: "Telegram",
|
||||||
|
contact_whatsapp: "WhatsApp",
|
||||||
|
contact_instagram: "Instagram",
|
||||||
|
form_header_title: "Start Your Journey",
|
||||||
|
form_header_subtitle: "Get personalized consultation",
|
||||||
|
form_name_label: "Full Name",
|
||||||
|
form_name_placeholder: "Enter your name",
|
||||||
|
form_phone_label: "Phone Number",
|
||||||
|
form_phone_placeholder: "+1 (555) 123-4567",
|
||||||
|
form_submit: "Get Free Consultation",
|
||||||
|
|
||||||
|
// Footer
|
||||||
|
footer_description: "Your trusted partner in university admission since 2018. We help students achieve their dreams of studying at top-tier universities worldwide.",
|
||||||
|
footer_exam_types: "Exam Types",
|
||||||
|
footer_services: "Services",
|
||||||
|
footer_contact: "Contact",
|
||||||
|
footer_our_method: "Our Method",
|
||||||
|
footer_success_stories: "Success Stories",
|
||||||
|
footer_free_consultation: "Free Consultation",
|
||||||
|
footer_get_started: "Get Started",
|
||||||
|
footer_telegram_support: "Telegram Support",
|
||||||
|
footer_email_us: "Email Us",
|
||||||
|
footer_copyright: "© 2025 ExamPass. All rights reserved. | Helping students achieve their university dreams since 2018.",
|
||||||
|
|
||||||
|
// Breadcrumbs
|
||||||
|
breadcrumb_home: "Home"
|
||||||
|
},
|
||||||
|
|
||||||
|
ru: {
|
||||||
|
// Navigation
|
||||||
|
nav_about: "О нас",
|
||||||
|
nav_exams: "Экзамены",
|
||||||
|
nav_contact: "Контакты",
|
||||||
|
|
||||||
|
// Hero Section
|
||||||
|
hero_title_line1: "СДАЙ ЛЮБОЙ ЭКЗАМЕН",
|
||||||
|
hero_title_line2: "ОДНИМ",
|
||||||
|
hero_title_click: "КЛИКОМ",
|
||||||
|
hero_description: "Гарантированное поступление в ведущие университеты мира. Наши революционные методы обеспечивают 100% успех - никаких курсов, только гарантированные результаты в Гарвард, Оксфорд, Кембридж и Стэнфорд.",
|
||||||
|
|
||||||
|
// Stats Section
|
||||||
|
stats_overline: "Наш Успех",
|
||||||
|
stats_title: "Наши Достижения",
|
||||||
|
stat_guarantee_title: "100% Гарантия",
|
||||||
|
stat_guarantee_desc: "Успешность с нашими революционными методами",
|
||||||
|
stat_years_title: "6 Лет",
|
||||||
|
stat_years_desc: "Гарантированных поступлений в университеты",
|
||||||
|
stat_students_title: "1000+ Студентов",
|
||||||
|
stat_students_desc: "Успешно поступили в ведущие университеты мира",
|
||||||
|
|
||||||
|
// Methodology Section
|
||||||
|
methodology_overline: "Что Мы Гарантируем",
|
||||||
|
methodology_title: "Революционные Методы",
|
||||||
|
|
||||||
|
// GMAT/GRE
|
||||||
|
gmat_title: "GMAT Focus Edition & GRE",
|
||||||
|
gmat_subtitle: "Бизнес и Аспирантура",
|
||||||
|
gmat_description: "Революционные аналитические методы для элитных бизнес-школ и университетов. Наш гарантированный подход обеспечивает поступление в магистратуру, MBA, Executive MBA и PhD в ведущих учреждениях.",
|
||||||
|
gmat_feature1: "Количественное Мышление",
|
||||||
|
gmat_feature2: "Вербальное Мышление",
|
||||||
|
gmat_feature3: "Аналитическое Письмо",
|
||||||
|
gmat_feature4: "Интегрированное Мышление",
|
||||||
|
|
||||||
|
// TOEFL/IELTS
|
||||||
|
toefl_title: "TOEFL iBT & IELTS Indicator",
|
||||||
|
toefl_subtitle: "Знание Английского",
|
||||||
|
toefl_description: "Экзамены, которые оценивают ваш уровень английского языка, их необходимо сдать для подачи заявки на любые международные программы обучения, эти экзамены являются самыми популярными среди международных экзаменов",
|
||||||
|
toefl_feature1: "Понимание Прочитанного",
|
||||||
|
toefl_feature2: "Навыки Аудирования",
|
||||||
|
toefl_feature3: "Разговорная Практика",
|
||||||
|
toefl_feature4: "Письменные Задания",
|
||||||
|
|
||||||
|
// Admission
|
||||||
|
admission_title: "Поступление За Границу",
|
||||||
|
admission_subtitle: "Подача Заявок в Университеты",
|
||||||
|
admission_description: "ТОП лучших университетов и бизнес-школ мира с гарантированным поступлением: Гарвард, Стэнфорд, Оксфорд, LBS, Кембридж; программы Master of Business Administration, Executive MBA, магистратура",
|
||||||
|
admission_feature1: "Гарвардский Университет",
|
||||||
|
admission_feature2: "Стэнфордский Университет",
|
||||||
|
admission_feature3: "Оксфордский Университет",
|
||||||
|
admission_feature4: "Кембриджский Университет",
|
||||||
|
|
||||||
|
// SAT/ACT
|
||||||
|
sat_title: "SAT & ACT",
|
||||||
|
sat_subtitle: "Поступление в Бакалавриат",
|
||||||
|
sat_description: "Стандартизированные тесты, необходимые для поступления в бакалавриат в колледжи и университеты США. Эти экзамены оценивают критическое мышление, решение проблем и академическую готовность к высшему образованию.",
|
||||||
|
sat_feature1: "Математика и Английский",
|
||||||
|
sat_feature2: "Критическое Чтение",
|
||||||
|
sat_feature3: "Написание Эссе",
|
||||||
|
sat_feature4: "Научное Мышление",
|
||||||
|
|
||||||
|
// About Section
|
||||||
|
about_overline: "О Нас",
|
||||||
|
about_title: "Мы",
|
||||||
|
about_gradient_text: "SnapPass",
|
||||||
|
about_large_text: "Команда экспертов, готовая изменить способ подготовки к экзаменам.",
|
||||||
|
about_highlight: "Забудьте о бессонных ночах и бесконечных курсах — мы делаем все по-другому.",
|
||||||
|
about_description: "С нами все просто и понятно: вы почувствуете уверенность уже после первого шага, а через несколько дней будете держать в руках официальное письмо о зачислении в ведущий университет.",
|
||||||
|
price_label: "Средняя Общая Стоимость",
|
||||||
|
price_amount: "15,000",
|
||||||
|
price_note: "Единственная компания, с которой никто не может конкурировать, уникальная и эксклюзивная",
|
||||||
|
|
||||||
|
// Success Section
|
||||||
|
success_overline: "Истории Успеха",
|
||||||
|
success_title: "Реальные Результаты",
|
||||||
|
success_subtitle: "Студенты, которые изменили свое будущее с нашей помощью",
|
||||||
|
|
||||||
|
// Contact Section
|
||||||
|
contact_heading_line1: "ГОТОВЫ",
|
||||||
|
contact_heading_line2: "К УСПЕХУ?",
|
||||||
|
contact_subheading: "Измените свое будущее сегодня. Присоединяйтесь к тысячам, которые достигли своих мечтаний с нашей экспертной помощью.",
|
||||||
|
contact_highlight: "Ваша история успеха начинается здесь.",
|
||||||
|
contact_telegram: "Телеграм",
|
||||||
|
contact_whatsapp: "Ватсап",
|
||||||
|
contact_instagram: "Инстаграм",
|
||||||
|
form_header_title: "Начните Свой Путь",
|
||||||
|
form_header_subtitle: "Получите персональную консультацию",
|
||||||
|
form_name_label: "Полное Имя",
|
||||||
|
form_name_placeholder: "Введите ваше имя",
|
||||||
|
form_phone_label: "Номер Телефона",
|
||||||
|
form_phone_placeholder: "+7 (999) 123-45-67",
|
||||||
|
form_submit: "Получить Бесплатную Консультацию",
|
||||||
|
|
||||||
|
// Footer
|
||||||
|
footer_description: "Ваш надежный партнер в поступлении в университет с 2018 года. Мы помогаем студентам достичь своих мечтаний об учебе в ведущих университетах мира.",
|
||||||
|
footer_exam_types: "Типы Экзаменов",
|
||||||
|
footer_services: "Услуги",
|
||||||
|
footer_contact: "Контакты",
|
||||||
|
footer_our_method: "Наш Метод",
|
||||||
|
footer_success_stories: "Истории Успеха",
|
||||||
|
footer_free_consultation: "Бесплатная Консультация",
|
||||||
|
footer_get_started: "Начать",
|
||||||
|
footer_telegram_support: "Поддержка в Телеграм",
|
||||||
|
footer_email_us: "Написать Нам",
|
||||||
|
footer_copyright: "© 2025 ExamPass. Все права защищены. | Помогаем студентам достичь своих университетских мечтаний с 2018 года.",
|
||||||
|
|
||||||
|
// Breadcrumbs
|
||||||
|
breadcrumb_home: "Главная"
|
||||||
|
}
|
||||||
|
};
|
18
src/robots.txt
Normal file
18
src/robots.txt
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
User-agent: *
|
||||||
|
Allow: /
|
||||||
|
|
||||||
|
# Sitemaps
|
||||||
|
Sitemap: https://exampass.com/sitemap.xml
|
||||||
|
|
||||||
|
# Crawl-delay for better server performance
|
||||||
|
Crawl-delay: 1
|
||||||
|
|
||||||
|
# Block access to certain directories
|
||||||
|
Disallow: /js/
|
||||||
|
Disallow: /css/
|
||||||
|
Disallow: /assets/universities/
|
||||||
|
|
||||||
|
# Allow access to important assets
|
||||||
|
Allow: /assets/logo/
|
||||||
|
Allow: /css/style.css
|
||||||
|
Allow: /js/main.js
|
3
zametki.txt
Normal file
3
zametki.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
нужно сделать meta ссылки для сайта
|
||||||
|
|
||||||
|
и нужно оптимизировать seo
|
Loading…
Reference in New Issue
Block a user