Documentation improvements and demo deep linking support#375
Conversation
- Update documentation links - Update RGB++ SDK repository link to RGBPlusPlus org - Add deprecation note for Lumos SDK - Remove rgbcat from project showcases
- Add ExampleGrid component with tag-based filtering and i18n support - Add code-examples page (English/Chinese) with playground and app examples - Add comprehensive Playground guide (English/Chinese) with Cell visualization - Add dictionary translations for examples section - Update navigation meta files to include new pages - Add Playground overview and Cell visualization images - Update uni-sat wallet integration documentation
Previously, navigating directly to a URL like /connected/Transfer would immediately redirect to the home page, even if the user had an active wallet session. This happened because the connected layout checked on mount — which is initially undefined while the CCC connector asynchronously restores the wallet session from localStorage — and triggered an eager redirect before restoration could complete. Additionally, users arriving via a deep link without a prior wallet connection were redirected to the home page with no way to return to their intended page after connecting. Changes: - Add hasSavedConnection() to check localStorage for a pending session restore, and defer the redirect with a grace period - Add saveReturnPath/consumeReturnPath using sessionStorage to implement a one-time return-URL pattern - Update home page and private-key page to redirect to the saved return path (defaulting to /connected) after wallet connection - Fix conflicting Tailwind classes in connectPrivateKey page
✅ Deploy Preview for liveccc ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for appccc ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for docsccc ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
✅ Deploy Preview for apiccc ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Code Review
This pull request adds a new code examples page, a comprehensive guide for the CCC Playground, and updates documentation links across various package READMEs. It also enhances the demo application with session restoration and return path preservation. The review feedback suggests removing the /en prefix from documentation links for consistent localization routing, adding defensive guards for window access to prevent SSR errors in Next.js, using a useRef to properly clear the session restoration timeout, and rendering a loading state instead of a blank screen during connection restoration.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| Fully enabling CKB's Turing completeness and cryptographic freedom power. | ||
| </p> | ||
|
|
||
| Check the [package documentation](https://docs.ckbccc.com/en/docs/packages/core-packages/ccc) and [API reference](https://api.ckbccc.com/modules/_ckb-ccc_ccc.index) for more details. |
There was a problem hiding this comment.
The pull request description mentions removing the /en prefix from documentation links for better i18n support. However, this newly added link explicitly includes the /en prefix. To ensure consistent localization routing, please remove the /en prefix here and across all other package README files.
| Check the [package documentation](https://docs.ckbccc.com/en/docs/packages/core-packages/ccc) and [API reference](https://api.ckbccc.com/modules/_ckb-ccc_ccc.index) for more details. | |
| Check the [package documentation](https://docs.ckbccc.com/docs/packages/core-packages/ccc) and [API reference](https://api.ckbccc.com/modules/_ckb-ccc_ccc.index) for more details. |
| export function saveReturnPath(path: string) { | ||
| window.sessionStorage.setItem(RETURN_TO_KEY, path); | ||
| } | ||
|
|
||
| export function consumeReturnPath(): string { | ||
| const path = window.sessionStorage.getItem(RETURN_TO_KEY); | ||
| window.sessionStorage.removeItem(RETURN_TO_KEY); | ||
| return path ?? "/connected"; | ||
| } | ||
|
|
||
| export function hasSavedConnection(): boolean { | ||
| try { | ||
| const info = JSON.parse( | ||
| window.localStorage.getItem("ccc-connection-info") ?? "{}", | ||
| ); | ||
| return !!(info.walletName && info.signerName); | ||
| } catch { | ||
| return false; | ||
| } | ||
| } |
There was a problem hiding this comment.
Since this utility file is used in a Next.js application, accessing window.sessionStorage and window.localStorage directly during Server-Side Rendering (SSR) will throw a ReferenceError: window is not defined if these functions are ever called or evaluated on the server. Adding defensive guards for typeof window !== "undefined" ensures SSR safety.
export function saveReturnPath(path: string) {
if (typeof window !== "undefined") {
window.sessionStorage.setItem(RETURN_TO_KEY, path);
}
}
export function consumeReturnPath(): string {
if (typeof window === "undefined") {
return "/connected";
}
const path = window.sessionStorage.getItem(RETURN_TO_KEY);
window.sessionStorage.removeItem(RETURN_TO_KEY);
return path ?? "/connected";
}
export function hasSavedConnection(): boolean {
if (typeof window === "undefined") {
return false;
}
try {
const info = JSON.parse(
window.localStorage.getItem("ccc-connection-info") ?? "{}",
);
return !!(info.walletName && info.signerName);
} catch {
return false;
}
}
There was a problem hiding this comment.
Good catch — while these are currently only called inside useEffect/event handlers in "use client" components (so never evaluated during SSR), adding the guards is cheap and future-proofs against accidental server-side usage. Applied.
| const [isRestoring, setIsRestoring] = useState(true); | ||
|
|
||
| // On mount, check if there's a saved connection to restore | ||
| useEffect(() => { | ||
| if (!signer) { | ||
| if (!hasSavedConnection()) { | ||
| setIsRestoring(false); | ||
| return; | ||
| } | ||
| // Give the connector a grace period to restore the session | ||
| const timer = setTimeout(() => setIsRestoring(false), 3000); | ||
| return () => clearTimeout(timer); | ||
| }, []); | ||
|
|
||
| // Clear restoring state as soon as signer appears | ||
| useEffect(() => { | ||
| if (signer) { | ||
| setIsRestoring(false); | ||
| } | ||
| }, [signer]); |
There was a problem hiding this comment.
The session restoration timer is set on mount but is not cleared if the signer becomes available before the 3-second timeout. This can lead to unnecessary state updates or race conditions. Storing the timer in a React.useRef allows you to clear it immediately when the signer is detected.
const [isRestoring, setIsRestoring] = useState(true);
const timerRef = React.useRef<NodeJS.Timeout | null>(null);
// On mount, check if there's a saved connection to restore
useEffect(() => {
if (!hasSavedConnection()) {
setIsRestoring(false);
return;
}
// Give the connector a grace period to restore the session
timerRef.current = setTimeout(() => setIsRestoring(false), 3000);
return () => {
if (timerRef.current) {
clearTimeout(timerRef.current);
}
};
}, []);
// Clear restoring state as soon as signer appears
useEffect(() => {
if (signer) {
setIsRestoring(false);
if (timerRef.current) {
clearTimeout(timerRef.current);
timerRef.current = null;
}
}
}, [signer]);
| if (!signer) { | ||
| return <>Disconnected</>; | ||
| return isRestoring ? null : <>Disconnected</>; | ||
| } |
There was a problem hiding this comment.
Returning null while isRestoring is true results in a completely blank screen for up to 3 seconds if the connection restoration is slow. Providing a loading state or a simple spinner significantly improves the user experience.
if (!signer) {
return isRestoring ? (
<div className="flex min-h-screen items-center justify-center">
<span className="text-sm text-gray-500">Restoring connection...</span>
</div>
) : (
<>Disconnected</>
);
}
- Replace ViewOptionsPopover with custom AskAiPopover component - Add i18n support for AI menu labels (askAi, askAiItems) - Use Radix Popover for centered positioning and blur-to-close behavior - Fix MarkdownCopyButton to work with i18n via rewrite to /[lang]/mdx - Remove index.mdx, redirect /docs to getting-started/introduction via proxy - Hide top nav links on docs pages (showNavLinks: false) - Fix llms.mdx route to handle slug with/without content.md suffix - Clean up unused getPageImage import

Summary
This PR improves the documentation experience and fixes deep linking to specific pages in the CCC App demo.
Changes
Documentation optimization
/enprefix from documentation links for better i18n supportRGBPlusPlusorganizationrgbcatfrom project showcase sectionNew documentation pages
playground, app,tool, etc.) and full i18n supportcode-examplespage (English/Chinese) showcasing runnable code examples with links to CCC Playground and CCC AppPlaygroundguide (English/Chinese) covering:Demo deep linking fix
/connected/*pages would immediately redirect to home page before wallet session restorationsessionStorage:/connectedif no return path existsconnectPrivateKeypageMotivation
The documentation improvements aim to provide a better developer experience with clearer navigation and up-to-date links. The new code-examples page consolidates Playground and App examples in a single filterable view, making it easier for users to discover relevant tools.
The deep linking fix enables users to share direct links to specific CCC App features (e.g.,
https://app.ckbccc.com/connected/Transfer) without being redirected to the home page, improving the app's usability as a standalone tool.