Найден корректный robots.txt
Файл управления сканированием сайта роботами
?
Robots.txt указывает поисковым роботам, какие страницы сканировать, а какие — нет. Ошибки в файле могут случайно закрыть важные разделы от индексации.
Кол-во редиректов для файла robots.txt 3 слишком большое! Это может вызывать затруднение при индексации поисковыми роботами!
Проверяемая страница не запрещена в robots.txt.
Цепочка редиректов для файла robots.txt:
http://vaultoro.com/robots.txt
301 MovedPermanently
https://vaultoro.com/robots.txt
301 MovedPermanently
https://trade.vaultoro.com/robots.txt
200 OK
Показать содержимое robots.txt
<!DOCTYPE html>
<html lang="en" class="app-dark" >
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/img/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vaultoro 2.0 — Self-Custody for Gold and Silver</title>
<!-- Cache Control - Prevent HTML caching to avoid stale chunk references -->
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<!-- CACHE FIX: Early cache clearing script for Safari -->
<script>
// Force SW update + cache clear on version change
(function() {
var BUILD_VERSION = '4.1.0+1786537885';
var lastVersion = localStorage.getItem('gp_build_version');
// Clear all caches
if ('caches' in window) {
caches.keys().then(function(names) {
names.forEach(function(name) { caches.delete(name); });
if (names.length > 0) console.log('[Cache] Cleared', names.length, 'caches');
});
}
// On version change: unregister SW and hard reload once
if (lastVersion && lastVersion !== BUILD_VERSION && 'serviceWorker' in navigator) {
localStorage.setItem('gp_build_version', BUILD_VERSION);
navigator.serviceWorker.getRegistrations().then(function(regs) {
var promises = regs.map(function(r) { return r.unregister(); });
Promise.all(promises).then(function() {
console.log('[SW] Unregistered stale service workers, reloading...');
window.location.reload();
});
});
return; // Stop execution — page will reload
}
localStorage.setItem('gp_build_version', BUILD_VERSION);
})();
</script>
<!-- Open Graph / Social Media Meta Tags (Fallback) -->
<meta name="description" content="Vaultoro 2.0: a self-custody platform for gold and silver. Holdings are represented on-chain as vGOLD and vSILVER, each backed 1:1 by allocated investment-grade metal in independent third-party custody." />
<link rel="canonical" href="https://trade.vaultoro.com/" />
<meta property="og:title" content="Vaultoro 2.0 — Self-Custody for Gold and Silver" />
<meta property="og:description" content="Vaultoro 2.0: a self-custody platform for gold and silver. Holdings are represented on-chain as vGOLD and vSILVER, each backed 1:1 by allocated investment-grade metal in independent third-party custody." />
<meta property="og:image" content="https://vaultoro.com/images/logo.png" />
<meta property="og:type" content="website" />
<meta property="og:site_name" content="Vaultoro" />
<meta property="og:url" content="https://trade.vaultoro.com/" />
<meta property="og:locale" content="en" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="Vaultoro 2.0 — Self-Custody for Gold and Silver" />
<meta name="twitter:description" content="Vaultoro 2.0: a self-custody platform for gold and silver. Holdings are represented on-chain as vGOLD and vSILVER, each backed 1:1 by allocated investment-grade metal in independent third-party custody." />
<meta name="twitter:image" content="https://vaultoro.com/images/logo.png" />
<!-- PWA Manifest -->
<link rel="manifest" href="/layout/app/manifest.json" />
<meta name="theme-color" content="#D4A72C" />
<!-- Icons -->
<link rel="icon" type="image/png" href="/img/favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="/img/favicon-16x16.png" sizes="16x16" />
<link rel="apple-touch-icon" sizes="180x180" href="/img/apple-touch-icon.png" />
<!-- iOS PWA Support -->
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="Vaultoro" />
<!-- Android PWA -->
<meta name="mobile-web-app-capable" content="yes" />
<!-- Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
<script src="https://kit.fontawesome.com/2b6622cebe.js" crossorigin="anonymous"></script>
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-NJHD5KS4');</script>
<!-- End Google Tag Manager -->
<style>
/* Initial loading screen - shows immediately before Vue loads */
#app-loader {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(137.44deg, #374151 3.33%, #1f2937 100.72%);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 9999;
transition: opacity 0.5s ease-out, visibility 0.5s ease-out;
}
#app-loader.hidden {
opacity: 0;
visibility: hidden;
}
.loader-icon {
width: 120px;
height: 120px;
margin-bottom: 2rem;
animation: float 3s ease-in-out infinite;
display: none; /* Hidden until branding is confirmed */
}
.loader-spinner {
width: 50px;
height: 50px;
border: 4px solid rgba(255, 255, 255, 0.3);
border-top-color: white;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes float {
0%, 100% {
transform: translateY(0px);
}
50% {
transform: translateY(-20px);
}
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
/* Ensure no white background flashes */
html, body {
margin: 0;
padding: 0;
background: #f8fafc;
font-family: 'Inter', sans-serif;
}
</style>
<script type="module" crossorigin src="/assets/index-DXKGPEPQ.js"></script>
<link rel="modulepreload" crossorigin href="/assets/axios-XIT0F8vi.js">
<link rel="modulepreload" crossorigin href="/assets/i18n-TlrTiTz9.js">
<link rel="modulepreload" crossorigin href="/assets/vue-CFtUG0ip.js">
<link rel="modulepreload" crossorigin href="/assets/web3-wagmi-ByCgLaaN.js">
<link rel="modulepreload" crossorigin href="/assets/primevue-DTdFS8kB.js">
<link rel="modulepreload" crossorigin href="/assets/crypto-polyfills-CWG2lENe.js">
<link rel="modulepreload" crossorigin href="/assets/web3-ethers-CeNfS6kJ.js">
<link rel="modulepreload" crossorigin href="/assets/web3-auth-C515XO8K.js">
<link rel="modulepreload" crossorigin href="/assets/pinia-C884aUOX.js">
<link rel="modulepreload" crossorigin href="/assets/web3-appkit-CxATEcsY.js">
<link rel="stylesheet" crossorigin href="/assets/index-D9r2kpI2.css">
</head>
<body class="min-h-screen">
<!-- Loading Screen - Shows immediately before Vue loads -->
<!-- Logo/colors are set by the script below (no hardcoded tenant) -->
<div id="app-loader">
<img alt="Loading" class="loader-icon" />
<div class="loader-spinner"></div>
</div>
<!-- Apply tenant branding synchronously before Vue loads -->
<script>
(function() {
function cleanTenantName(name) {
return (name || '').replace(/\s*[\(\[\-\u2013\u2014]?\s*(dev|stage\d*|staging|development|test)\s*[\)\]]?\s*/gi, '').trim();
}
function setFavicon(path) {
if (!path) return;
var links = document.querySelectorAll('link[rel="icon"], link[rel="shortcut icon"]');
if (!links.length) {
var link = document.createElement('link');
link.rel = 'icon';
document.head.appendChild(link);
links = [link];
}
for (var i = 0; i < links.length; i++) {
links[i].href = path;
}
}
function setMetaContent(selector, content) {
if (!content) return;
var el = document.querySelector(selector);
if (el) el.setAttribute('content', content);
}
function applyLoaderBranding(settings) {
if (!settings || !settings.branding) return false;
var loader = document.getElementById('app-loader');
if (!loader) return false;
var b = settings.branding;
var meta = settings.meta || {};
var c1 = (b.colors && b.colors.secondary && b.colors.secondary['400']) || '#5EDCE7';
var c2 = (b.colors && b.colors.primary && b.colors.primary['500']) || '#895CFE';
loader.style.background = 'linear-gradient(137.44deg, ' + c1 + ' 3.33%, ' + c2 + ' 100.72%)';
var img = loader.querySelector('.loader-icon');
var icon = b.logoIcon || b.logo;
if (img && icon) {
img.src = icon;
img.style.display = 'block';
}
var cleanName = cleanTenantName(settings.name);
var metaTitle = meta.title || cleanName;
var metaDesc = meta.description;
var origin = window.location.origin;
var ogImage = b.ogImage || meta.ogImage;
if (ogImage && ogImage.charAt(0) === '/') {
ogImage = origin + ogImage;
}
if (metaTitle) {
document.title = metaTitle;
setMetaContent('meta[property="og:title"]', metaTitle);
setMetaContent('meta[name="twitter:title"]', metaTitle);
}
if (metaDesc) {
setMetaContent('meta[name="description"]', metaDesc);
setMetaContent('meta[property="og:description"]', metaDesc);
setMetaContent('meta[name="twitter:description"]', metaDesc);
}
if (cleanName) {
setMetaContent('meta[property="og:site_name"]', cleanName);
}
if (ogImage) {
setMetaContent('meta[property="og:image"]', ogImage);
setMetaContent('meta[name="twitter:image"]', ogImage);
}
setMetaContent('meta[property="og:url"]', origin + window.location.pathname);
if (b.favicon) {
setFavicon(b.favicon);
}
var themeColor = meta.themeColor || (b.colors && b.colors.primary && b.colors.primary['500']);
if (themeColor) {
setMetaContent('meta[name="theme-color"]', themeColor);
}
var appTitle = meta.appleWebAppTitle || cleanName;
if (appTitle) {
setMetaContent('meta[name="apple-mobile-web-app-title"]', appTitle);
}
// Correct canonical to this tenant's actual origin so a shared
// index.html never leaks a different tenant's canonical URL.
var canonicalEl = document.querySelector('link[rel="canonical"]');
if (canonicalEl) {
canonicalEl.setAttribute('href', origin + '/');
}
return true;
}
var tenantBootstrap = {"vaultoro":{"subdomain":"vaultoro","name":"Vaultoro","branding":{"logo":"/images/whitelabel/vaultoro/logo.svg","logoIcon":"/images/whitelabel/vaultoro/logo.svg","favicon":"/images/whitelabel/vaultoro/favicon.ico","ogImage":"https://vaultoro.com/images/logo.png","colors":{"primary":{"500":"#D4A72C"},"secondary":{"400":"#6971F7"}}},"meta":{"title":"Vaultoro 2.0 — Self-Custody for Gold and Silver","description":"Vaultoro 2.0: a self-custody platform for gold and silver. Holdings are represented on-chain as vGOLD and vSILVER, each backed 1:1 by allocated investment-grade metal in independent third-party custody.","keywords":"vaultoro, vGOLD, vSILVER, gold, silver, self-custody, crypto","locale":"en","themeColor":"#D4A72C","appleWebAppTitle":"Vaultoro"}}};
// Detect current subdomain (mirrors src/utils/subdomain.js logic)
var currentSub = '';
var h = window.location.hostname;
// Priority 1: Vaultoro-owned domains (*.vaultoro.com)
if (h === 'vaultoro.com' || h.slice(-13) === '.vaultoro.com') {
currentSub = 'vaultoro';
}
var customDomainTenants = {
'app-stage1.vaultoro.com': 'vaultoro'
};
// Priority 2: exact/custom domain mapping. This wins over a generic
// build-time VITE_TENANT because the same stage bundle can serve
// gift-stage1.utribe.app and app-stage1.vaultoro.com.
if (!currentSub) {
for (var domain in customDomainTenants) {
if (Object.prototype.hasOwnProperty.call(customDomainTenants, domain) &&
(h === domain || h.slice(-(domain.length + 1)) === '.' + domain)) {
currentSub = customDomainTenants[domain];
break;
}
}
}
// Priority 3: VITE_TENANT env var (injected by Vite at build/dev time)
var envTenant = '';
if (!currentSub && envTenant && envTenant !== '%' + 'VITE_TENANT' + '%') {
currentSub = envTenant;
}
if (!currentSub) {
// Keep in sync with KNOWN_TENANTS in src/utils/subdomain.js
var knownTenants = ['gift','vaultoro','stage1','utribe','gift-stage1'];
if (h === 'localhost' || h === '127.0.0.1' || /^(\d{1,3}\.){3}\d{1,3}$/.test(h)) {
currentSub = localStorage.getItem('dev_subdomain') || 'stage1';
} else {
var parts = h.split('.');
if (parts.length >= 3) {
var sub = parts[0].toLowerCase();
var excluded = ['www','api','admin','staging','dev','test'];
if (excluded.indexOf(sub) !== -1) {
currentSub = 'default';
} else if (knownTenants.indexOf(sub) !== -1) {
currentSub = sub;
} else {
// Scan remaining parts for a known tenant
// e.g. app-stage1.vaultoro.com -> "vaultoro"
currentSub = sub;
for (var i = 1; i < parts.length - 1; i++) {
if (knownTenants.indexOf(parts[i].toLowerCase()) !== -1) {
currentSub = parts[i].toLowerCase();
break;
}
}
}
} else {
currentSub = 'default';
}
}
}
// Apply tenant defaults immediately so reloads never show default GIFT branding.
applyLoaderBranding(tenantBootstrap[currentSub]);
try {
var persistedStore = sessionStorage.getItem('whitelabel');
if (persistedStore) {
var parsedStore = JSON.parse(persistedStore);
var persistedSubdomain = parsedStore && (parsedStore.subdomain || (parsedStore.settings && parsedStore.settings.subdomain));
if (persistedSubdomain && persistedSubdomain !== currentSub) {
sessionStorage.removeItem('whitelabel');
}
}
var raw = sessionStorage.getItem('whitelabel_settings');
if (raw) {
var parsed = JSON.parse(raw);
if (parsed && parsed.settings && (Date.now() - parsed.timestamp < 300000)) {
var s = parsed.settings;
// Only use cache if subdomain matches current tenant
if (s.subdomain === currentSub) {
applyLoaderBranding(s);
} else if (s.subdomain) {
sessionStorage.removeItem('whitelabel_settings');
}
}
}
} catch(e) {}
})();
</script>
<div id="app"></div>
<!-- <elevenlabs-convai agent-id="BlVEpv7anKb3ZshzjK2g"></elevenlabs-convai><script src="https://unpkg.com/@elevenlabs/convai-widget-embed" async type="text/javascript"></script> -->
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-NJHD5KS4" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->
</body>
</html>