fix: add canonical URLs, unique meta descriptions, and hreflang tags

- Add canonical URL to all pages
- Fix duplicate meta descriptions across 4 pages
- Add hreflang tags for en/ja/zh-CN/x-default
- Remove llms.txt rewrite rule causing 500 error in .htaccess
This commit is contained in:
qingjie.du
2026-06-21 12:22:24 +09:00
parent e93b48345c
commit 506989660b
7 changed files with 1005 additions and 185 deletions

View File

@@ -11,7 +11,14 @@
content="width=device-width, initial-scale=1.0"
/>
<title> Integration - amiPro </title>
<title>Passkey Integration Guide - 15-Minute Setup | amiPro</title>
<link rel="canonical" href="https://amipro.me/integration.html" />
<!-- Hreflang -->
<link rel="alternate" hreflang="en" href="https://amipro.me/integration.html" />
<link rel="alternate" hreflang="ja" href="https://amipro.me/ja/integration.html" />
<link rel="alternate" hreflang="zh-CN" href="https://amipro.me/zh-CN/integration.html" />
<link rel="alternate" hreflang="x-default" href="https://amipro.me/integration.html" />
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-850DCHX9EJ"></script>
@@ -23,7 +30,39 @@
gtag('config', 'G-850DCHX9EJ');
</script>
<meta name="description" content="the easiest to integrate Passkey cloud service" />
<meta name="description" content="Step-by-step guide to integrate amiPro FIDO2 passkey authentication. Drop-in JavaScript SDK, device management, and session control in 15 minutes." />
<!-- Open Graph -->
<meta property="og:type" content="article" />
<meta property="og:title" content="Passkey Integration Guide - 15-Minute Setup | amiPro" />
<meta property="og:description" content="Step-by-step guide to integrate amiPro FIDO2 passkey authentication. Drop-in JavaScript SDK, device management, and session control in 15 minutes." />
<meta property="og:url" content="https://amipro.me/integration.html" />
<meta property="og:site_name" content="amiPro" />
<meta property="og:image" content="https://amipro.me/files/build.jpg" />
<!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="Passkey Integration Guide - 15-Minute Setup | amiPro" />
<meta name="twitter:description" content="Step-by-step guide to integrate amiPro FIDO2 passkey authentication. Drop-in JavaScript SDK, device management, and session control in 15 minutes." />
<meta name="twitter:image" content="https://amipro.me/files/build.jpg" />
<!-- JSON-LD Article -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "Passkey Integration Guide - 15-Minute Setup",
"description": "Step-by-step guide to integrate amiPro FIDO2 passkey authentication. Drop-in JavaScript SDK, device management, and session control in 15 minutes.",
"url": "https://amipro.me/integration.html",
"publisher": {
"@type": "Organization",
"name": "amiPro",
"url": "https://amipro.me"
},
"image": "https://amipro.me/files/build.jpg",
"mainEntityOfPage": "https://amipro.me/integration.html"
}
</script>
<!-- Favicon -->
<link rel="icon" type="image/x-icon" href="files/favicon.ico" />
@@ -75,164 +114,182 @@
const i18n_messages = new Map();
var lang_map = new Map();
lang_map.set("en-US", "amiPro - The easiest-to-integrate Passkey cloud service");
lang_map.set("en", "amiPro - The easiest-to-integrate Passkey cloud service");
lang_map.set("zh-CN", "amiPro - 最易集成的Passkey云服务");
lang_map.set("ja", "amiPro - 最も簡単に統合できるパスキー・クラウド・サービス");
i18n_messages.set("label_welcome", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Sample site");
lang_map.set("en", "Sample site");
lang_map.set("zh-CN", "示例网站");
lang_map.set("ja", "サンプルサイト");
i18n_messages.set("label_sample", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Contact us (sales@amipro.me)");
lang_map.set("en", "Contact us (sales@amipro.me)");
lang_map.set("zh-CN", "联系我们sales@amipro.me");
lang_map.set("ja", "お問い合わせsales@amipro.me");
i18n_messages.set("title_contact", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Contact us (sales@amipro.me)");
lang_map.set("en", "Contact us (sales@amipro.me)");
lang_map.set("zh-CN", "联系我们sales@amipro.me");
lang_map.set("ja", "お問い合わせsales@amipro.me");
i18n_messages.set("title_contact_cta", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Three month free trial<br>(After free registration of the management portal, all functions are free to try for three months)<br>No credit card required.");
lang_map.set("en", "Three month free trial<br>(After free registration of the management portal, all functions are free to try for three months)<br>No credit card required.");
lang_map.set("zh-CN", "三个月免费试用<br>(免费注册管理门户后,所有功能免费试用三个月)<br> 无需信用卡");
lang_map.set("ja", "3ヶ月間の無料トライアル<br>管理ポータルの無料登録後、すべての機能を3ヶ月間無料でお試しいただけます<br> クレジットカードは不要です。");
i18n_messages.set("btn_portal", lang_map);
lang_map = new Map();
lang_map.set("en-US", "How to integrate");
lang_map.set("en", "How to integrate");
lang_map.set("zh-CN", "如何集成");
lang_map.set("ja", "統合方法");
i18n_messages.set("label_integartion_title", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Step1: Open sample site");
lang_map.set("en", "Step1: Open sample site");
lang_map.set("zh-CN", "步骤1: 打开示例网站");
lang_map.set("ja", "ステップ1: サンプルサイトを開く");
i18n_messages.set("btn_step1", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Click the following link to enter the sample website. In the following instructions you will need to refer to the source code of the sample website. <br><a href='https://sample.amipro.me/modal-demo.html' target='_blank'>https://sample.amipro.me/modal-demo.html</a>");
lang_map.set("en", "Click the following link to enter the sample website. In the following instructions you will need to refer to the source code of the sample website. <br><a href='https://sample.amipro.me/modal-demo.html' target='_blank'>https://sample.amipro.me/modal-demo.html</a>");
lang_map.set("zh-CN", "点击以下链接,进入示例网站。在以下的说明中您将需要参考示例网站的源代码。<br><a href='https://sample.amipro.me/modal-demo.html' target='_blank'>https://sample.amipro.me/modal-demo.html</a>");
lang_map.set("ja", "以下のリンクをクリックして、サンプルサイトに入ってください。以下の説明では、サンプルサイトのソースコードを参照する必要があります。<br><a href='https://sample.amipro.me/modal-demo.html' target='_blank'>https://sample.amipro.me/modal-demo.html</a>");
i18n_messages.set("info_top_step1", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Step2: Login page integration");
lang_map.set("en", "Step2: Login page integration");
lang_map.set("zh-CN", "步骤2: 登录页面集成");
lang_map.set("ja", "ステップ2: ログインページの統合");
i18n_messages.set("btn_step2", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Reference the sample site to introduce the amiPro JavaScript SDK and call the Passkey login integration API with UI.");
lang_map.set("en", "Reference the sample site to introduce the amiPro JavaScript SDK and call the Passkey login integration API with UI.");
lang_map.set("zh-CN", "参考示例网站在登录页面引入amiPro JavaScript SDK并调用带UI的 Passkey 登录集成API。");
lang_map.set("ja", "サンプルサイトを参考にして、amiPro JavaScript SDK を導入し、UI付きのパスキー・ログイン統合 API を呼び出します。");
i18n_messages.set("info_top_step2", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Step3: Build devices management page");
lang_map.set("en", "Step3: Build devices management page");
lang_map.set("zh-CN", "步骤3: 构建设备管理页面");
lang_map.set("ja", "ステップ3: デバイス管理ページの構築");
i18n_messages.set("btn_step3", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Refer to the example website, include the amiPro JavaScript SDK on the appropriate page after login, and call the device management integration API with UI.");
lang_map.set("en", "Refer to the example website, include the amiPro JavaScript SDK on the appropriate page after login, and call the device management integration API with UI.");
lang_map.set("zh-CN", "参考示例网站在登录后的适当页面引入amiPro JavaScript SDK并调用带UI的设备管理集成API。");
lang_map.set("ja", "サンプルサイトを参考にして、ログイン後の適切なページにamiPro JavaScript SDKを導入し、UI付きのデバイス管理統合APIを呼び出します。");
i18n_messages.set("info_top_step3", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Step4: Session management");
lang_map.set("en", "Step4: Session management");
lang_map.set("zh-CN", "步骤4: 会话管理");
lang_map.set("ja", "ステップ4: セッション管理");
i18n_messages.set("btn_step4", lang_map);
lang_map = new Map();
lang_map.set("en-US", "There are two methods of session management:<br>Method 1. Use amiPro's validSession API to manage sessions. Refer to the setSessionStatus function in <a href='https://sample.amipro.me/modal-demo.html' target='_blank'>https://sample.amipro.me/modal-demo.html</a>. <br>Method 2: Use your website's original session management, just call amiPro's logoutFido2UserSession function in your website's original session timeout processing.");
lang_map.set("en", "There are two methods of session management:<br>Method 1. Use amiPro's validSession API to manage sessions. Refer to the setSessionStatus function in <a href='https://sample.amipro.me/modal-demo.html' target='_blank'>https://sample.amipro.me/modal-demo.html</a>. <br>Method 2: Use your website's original session management, just call amiPro's logoutFido2UserSession function in your website's original session timeout processing.");
lang_map.set("zh-CN", "会话管理有两种方式:<br>方式1、使用amiPro的validSession API 管理会话。参考<a href='https://sample.amipro.me/modal-demo.html' target='_blank'>https://sample.amipro.me/modal-demo.html</a>中的setSessionStatus函数。<br>方式2、使用您的网站原有的会话管理只需在您的网站原有的会话超时的处理中调用amiPro的logoutFido2UserSession函数。");
lang_map.set("ja", "セッション管理は2つ方法があります:<br>方法 1: amiPro の validSession API を使用してセッションを管理します。<a href='https://sample.amipro.me/modal-demo.html' target='_blank'>https://sample.amipro.me/modal-demo.html</a>にあるsetSessionStatus関数を参考してください。 <br>方法 2: Web サイトの既存のセッション管理を使用します。Web サイトの既存のセッションのタイムアウト処理の中に、 amiPro の logoutFido2UserSession 関数を呼び出すだけで管理出来ます。");
i18n_messages.set("info_top_step4", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Step5: Management Portal registration");
lang_map.set("en", "Step5: Management Portal registration");
lang_map.set("zh-CN", "步骤5: 管理门户注册");
lang_map.set("ja", "ステップ5: 管理ポータル登録");
i18n_messages.set("btn_step5", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Use your email address to register amiPro management portal for free:<br>1. Please use the PC and other devices you plan to manage amiPro and open the following link with your browser. <br><a href='https://portal.amipro.me/'>https://portal.amipro.me</a><br>2. In the management portal, enter your email address and click the [Create Account/Add new device] link. <br>3. Use the same browser to open the link in the email you received and add the device<br>4. Click [Go to top page] and use the added device [Passkey Login].<br><img src='files/portal_reg_en.jpg' width=50%>");
lang_map.set("en", "Use your email address to register amiPro management portal for free:<br>1. Please use the PC and other devices you plan to manage amiPro and open the following link with your browser. <br><a href='https://portal.amipro.me/'>https://portal.amipro.me</a><br>2. In the management portal, enter your email address and click the [Create Account/Add new device] link. <br>3. Use the same browser to open the link in the email you received and add the device<br>4. Click [Go to top page] and use the added device [Passkey Login].<br><img src='files/portal_reg_en.jpg' width=50%>");
lang_map.set("zh-CN", "使用您的邮件地址免费注册amiPro管理门户: <br>1、请用您准备管理amiPro的PC等设备及其浏览器打开以下链接。<br><a href='https://portal.amipro.me/'>https://portal.amipro.me</a><br>2、在管理门户中输入您的邮件地址并点击【创建新账号或添加新设备】链接。<br>3、使用相同的浏览器打开您收到的邮件中的链接并添加设备<br>4、点击【去首页】使用添加的设备【Passkey登录】进入管理门户。<br><img src='files/portal_reg_jp.jpg' width=50%>");
lang_map.set("ja", "電子メール アドレスを使用して、amiPro 管理ポータルに無料でサインアップします: <br>1. amiPro を管理する予定の PC およびその他のデバイスを使用し、ブラウザで次のリンクを開いてください。 <br><a href='https://portal.amipro.me/'>https://portal.amipro.me</a><br>2. 管理ポータルで、電子メール アドレスを入力し、[アカウントを作成・新しいデバイスを追加] リンクをクリックしてください。 <br>3. 受信した電子メールにあるURLを同じブラウザで開いてデバイスを追加してください。<br>4. [トップページへ] をクリックして、登録したデバイスで[パスキーでログイン]でログインして、トップページへ。<br><img src='files/portal_reg_jp.jpg' width=50%>");
i18n_messages.set("info_top_step5", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Step: FIDO2 server settings");
lang_map.set("en", "Step: FIDO2 server settings");
lang_map.set("zh-CN", "步骤6: FIDO2服务器设置");
lang_map.set("ja", "ステップ6: FIDO2 サーバー設定");
i18n_messages.set("btn_step6", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Advanced Custom Deployment");
lang_map.set("en", "Advanced Custom Deployment");
lang_map.set("zh-CN", "深入定制部署");
lang_map.set("ja", "高度なカスタムデプロイメント");
i18n_messages.set("label_custom_deploy_title", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Web Component integration, custom UI, and backend API integration for advanced deployment options");
lang_map.set("en", "Web Component integration, custom UI, and backend API integration for advanced deployment options");
lang_map.set("zh-CN", "Web Component 集成、自定义 UI 和后端 API 集成等高级部署选项");
lang_map.set("ja", "高度なデプロイメントオプションについては、Web Component統合、カスタムUI、バックエンドAPI統合");
i18n_messages.set("label_custom_deploy_desc", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Advanced Custom Deployment →");
lang_map.set("en", "Advanced Custom Deployment →");
lang_map.set("zh-CN", "深入定制部署 →");
lang_map.set("ja", "高度なカスタムデプロイメント →");
i18n_messages.set("btn_custom_deploy", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Click [Settings] on the Portal left menu, and then click [Add] on the right page. Enter your website domain name (the port number cannot be included), and note that your website needs to use the HTTPS protocol. <br>【[Device Registration Page] is a link to the page where device management was integrated in step 3. <br>Other settings can be left as default. Click [Submit] to complete the settings.<br><img src='files/portal_conf_en.jpg' width=80%>");
lang_map.set("en", "Click [Settings] on the Portal left menu, and then click [Add] on the right page. Enter your website domain name (the port number cannot be included), and note that your website needs to use the HTTPS protocol. <br>【[Device Registration Page] is a link to the page where device management was integrated in step 3. <br>Other settings can be left as default. Click [Submit] to complete the settings.<br><img src='files/portal_conf_en.jpg' width=80%>");
lang_map.set("zh-CN", "点击管理门户左侧菜单中的【设定】之后点击右侧页面中的【添加】。输入您的网站域名不能包含端口号注意您的网站需要使用HTTPS协议。<br>【[设备注册页面] 是在步骤 3 中集成设备管理功能的页面链接。<br>其他设置可以保留默认值。最后需要点击【提 交】完成设定。<br><img src='files/portal_conf_jp.jpg' width=80%>");
lang_map.set("ja", "管理ポータル左メニューの[設定]をクリックし、右ページの[追加]をクリックしてください。 Web サイトのドメイン名を入力します (ポート番号は含めることはできません)。Web サイトでは HTTPS プロトコルを使用する必要があることに注意してください。 <br>【デバイス登録ページ】は手順3でデバイス管理を統合したページへのリンクです。<br>そのたの設定はデフォルトでよい、最後は送信をクリックして設定完了<br><img src='files/portal_conf_jp.jpg' width=80%>");
i18n_messages.set("info_top_step6", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Ship Passkeys in 15 Minutes");
lang_map.set("en", "Ship Passkeys in 15 Minutes");
lang_map.set("zh-CN", "在15分钟内部署Passkey");
lang_map.set("ja", "15分でパスキーを導入");
i18n_messages.set("hero_title", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Follow the production-proven playbook: explore the sample site, drop in the JavaScript SDK, fine-tune device management, and configure the amiPro portal for your domains.");
lang_map.set("en", "Follow the production-proven playbook: explore the sample site, drop in the JavaScript SDK, fine-tune device management, and configure the amiPro portal for your domains.");
lang_map.set("zh-CN", "遵循已在生产中验证的流程:查看示例站点,嵌入 JavaScript SDK微调设备管理并为您的域配置 amiPro 门户。");
lang_map.set("ja", "本番で実績のある手順に従ってください: サンプルサイトを確認し、JavaScript SDK を導入し、デバイス管理を調整し、amiPro ポータルをドメインに対して設定します。");
i18n_messages.set("hero_lead", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Browser + App SDK");
lang_map.set("en", "Browser + App SDK");
lang_map.set("zh-CN", "浏览器 + 应用 SDK");
lang_map.set("ja", "ブラウザ + アプリ SDK");
i18n_messages.set("hero_chip_1", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Recovery-ready");
lang_map.set("en", "Recovery-ready");
lang_map.set("zh-CN", "支持恢复");
lang_map.set("ja", "リカバリ対応");
i18n_messages.set("hero_chip_2", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Session control");
lang_map.set("en", "Session control");
lang_map.set("zh-CN", "会话控制");
lang_map.set("ja", "セッション制御");
i18n_messages.set("hero_chip_3", lang_map);
lang_map = new Map();
lang_map.set("en", "Need white-glove integration help?");
lang_map.set("ja", "手厚いインテグレーションサポートが必要ですか?");
i18n_messages.set("cta_title", lang_map);
lang_map = new Map();
lang_map.set("en", "Share your stack and we will tailor the SDK sample for you.");
lang_map.set("ja", "お使いのスタックをお教えください。SDKサンプルをカスタマイズいたします。");
i18n_messages.set("cta_desc", lang_map);
lang_map = new Map();
lang_map.set("en", "Talk to us");
lang_map.set("ja", "お問い合わせ");
i18n_messages.set("cta_btn", lang_map);
window.onload = async function() {
setI18NText(i18n_messages)
initRevealAnimations()
if (typeof createLanguageSelector === 'function') {
document.body.appendChild(createLanguageSelector());
}
}
</script>
@@ -331,10 +388,10 @@
<div class="cta-banner" data-animate>
<div>
<h4>Need white-glove integration help?</h4>
<p style="margin: 0; color: var(--text-muted);">Share your stack and we will tailor the SDK sample for you.</p>
<h4 id="cta_title">Need white-glove integration help?</h4>
<p style="margin: 0; color: var(--text-muted);" id="cta_desc">Share your stack and we will tailor the SDK sample for you.</p>
</div>
<a href="mailto:sales@amipro.me?subject=amiPro%20integration" class="btn btn-primary">Talk to us</a>
<a href="mailto:sales@amipro.me?subject=amiPro%20integration" class="btn btn-primary" id="cta_btn">Talk to us</a>
</div>
<!-- / Content -->