Skip to content

High-level navigation enhancements #2074

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 47 commits into from
Jun 13, 2025
Merged
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
565d9e9
Migrate gator docs
alexandratran May 23, 2025
11523bd
fixes
alexandratran May 23, 2025
598c837
swizzle desktop sidebar
alexandratran May 23, 2025
ff8d86b
update codeowners
alexandratran May 23, 2025
87b1020
Add initial dropdown component.
bgravenorst May 26, 2025
cd23897
Add front page.
bgravenorst May 27, 2025
a12367a
Update SDK connect guides
alexandratran May 30, 2025
03a1139
Merge branch 'main' into migrate-gator
alexandratran Jun 2, 2025
5f3a239
Fix category sections.
bgravenorst Jun 2, 2025
f341ae4
Inital dropdown style changes.
bgravenorst Jun 3, 2025
7a1c453
Update dropdown behaviour.
bgravenorst Jun 4, 2025
bf1448e
Add link to Embedded wallets (#2069)
bgravenorst Jun 2, 2025
000cf1e
Minor update. (#2070)
bgravenorst Jun 2, 2025
7ad0f3a
Update react-native.md (#2068)
RobItu Jun 3, 2025
e342ba9
chore(deps): bump tar-fs from 1.16.4 to 1.16.5 in the npm_and_yarn gr…
dependabot[bot] Jun 3, 2025
00f115a
fixes
alexandratran May 23, 2025
0d88cff
Add front page.
bgravenorst May 27, 2025
e9f6fed
Remove dup.
bgravenorst Jun 4, 2025
5c1df47
High-level navigation changes
alexandratran Jun 4, 2025
088d266
add get started button
alexandratran Jun 4, 2025
558a954
Merge branch 'main' into sdk-connect
alexandratran Jun 4, 2025
c31ebea
updates to sdk intro + redirects
alexandratran Jun 4, 2025
1feffcb
Merge branch 'main' into migrate-gator
alexandratran Jun 4, 2025
5c0dd5e
add api reference docs and fix links
alexandratran Jun 4, 2025
4e9c9b8
Merge branch 'migrate-gator' into nav-enhancements
alexandratran Jun 4, 2025
7415a8d
minor adjustments
alexandratran Jun 5, 2025
3fdde08
address feedback
alexandratran Jun 5, 2025
0873bb4
move llm prompt and update copy
alexandratran Jun 5, 2025
f72b52e
Merge branch 'main' into migrate-gator
alexandratran Jun 6, 2025
9c54eab
change file names (delegation-toolkit) and fix links
alexandratran Jun 6, 2025
1c8e299
fix lint error
alexandratran Jun 6, 2025
d03d348
Merge branch 'main' into sdk-connect
alexandratran Jun 6, 2025
c57df56
Merge branch 'migrate-gator' into nav-enhancements
alexandratran Jun 6, 2025
b352c5a
Merge branch 'sdk-connect' into nav-enhancements
alexandratran Jun 6, 2025
5370a11
Add product banner
alexandratran Jun 7, 2025
37899c2
Merge branch 'main' into nav-enhancements
alexandratran Jun 9, 2025
666897c
update icons
alexandratran Jun 9, 2025
d0d49fb
minor fix
alexandratran Jun 9, 2025
310f9dc
Merge branch 'main' into migrate-gator
alexandratran Jun 10, 2025
54709d1
fix version ordering and color mode
alexandratran Jun 10, 2025
7d9af66
Merge branch 'main' into nav-enhancements
alexandratran Jun 10, 2025
c461585
Merge branch 'migrate-gator' into nav-enhancements
alexandratran Jun 10, 2025
b8bf06a
hide top nav + enhancements
alexandratran Jun 11, 2025
4f95976
Merge branch 'main' into nav-enhancements
alexandratran Jun 11, 2025
42cb2a2
fix embedded wallets sdk dropdown
alexandratran Jun 11, 2025
56cf4f4
fix sidebar bug
alexandratran Jun 11, 2025
cdb62f9
address reviewer feedback
alexandratran Jun 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions delegation-toolkit/index.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
---
title: Introduction to the MetaMask Delegation Toolkit
title: Delegation Toolkit introduction
sidebar_label: Introduction
description: High-level overview of the Delegation Toolkit, its benefits, and where to start in the documentation.
sidebar_position: 1
---

import CardList from "@site/src/components/CardList"

# MetaMask Delegation Toolkit
# Embed smart accounts using the Delegation Toolkit

The MetaMask Delegation Toolkit is a [Viem](https://viem.sh/)-based collection of tools for integrating
embedded smart contract wallets, known as [MetaMask smart accounts](concepts/smart-accounts.md),
3 changes: 2 additions & 1 deletion developer-tools/dashboard/index.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
---
sidebar_label: Introduction
title: Developer dashboard introduction
description: Documentation for using the MetaMask Developer dashboard
sidebar_position: 1
---

import CardList from '@site/src/components/CardList'
import Banner from '@site/src/components/Banner'

# Developer dashboard documentation
# Introduction

The [MetaMask Developer dashboard](https://developer.metamask.io/) provides developers with a
comprehensive overview and control of their Infura service.
47 changes: 30 additions & 17 deletions docusaurus.config.js
Original file line number Diff line number Diff line change
@@ -15,6 +15,9 @@ const codeTheme = themes.dracula
const remarkCodesandbox = require('remark-codesandbox')
const isProd = process.env.NODE_ENV === 'production'
const helpDropdown = fs.readFileSync("./src/components/NavDropdown/DeveloperTools.html", "utf-8");
const connectDropdown = fs.readFileSync("./src/components/NavDropdown/ConnectMetaMask.html", "utf-8");
const embedDropdown = fs.readFileSync("./src/components/NavDropdown/EmbedMetaMask.html", "utf-8");
const extendDropdown = fs.readFileSync("./src/components/NavDropdown/ExtendScale.html", "utf-8");
/** @type {import('@docusaurus/types').Config} */
const config = {
title: 'MetaMask developer documentation',
@@ -225,33 +228,43 @@ const config = {
respectPrefersColorScheme: true,
},
navbar: {
title: ' │ ‎ Documentation',
logo: {
alt: 'MetaMask logo',
src: 'img/metamask-logo.svg',
srcDark: 'img/metamask-logo-dark.svg',
width: 150,
},
hideOnScroll: true,
items: [
{
to: 'sdk',
label: 'SDK',
},
{
to: 'wallet',
label: 'Wallet API',
},
{
to: 'delegation-toolkit',
label: 'Delegation Toolkit',
type: 'dropdown',
label: 'Connect to MetaMask',
items: [
{
type: "html",
value: connectDropdown,
},
],
},
{
to: 'snaps',
label: 'Snaps',
type: 'dropdown',
label: 'Embed MetaMask',
items: [
{
type: "html",
value: embedDropdown,
},
],
},
{
to: 'services',
label: 'Services',
type: 'dropdown',
label: 'Extend and scale',
items: [
{
type: "html",
value: extendDropdown,
},
],
},
{
type: 'dropdown',
@@ -333,15 +346,15 @@ const config = {
href: 'https://github.com/MetaMask/metamask-docs',
},
{
label: 'MetaMask wallet GitHub',
label: 'MetaMask extension GitHub',
href: 'https://github.com/MetaMask/metamask-extension/',
},
{
label: 'MetaMask SDK GitHub',
href: 'https://github.com/MetaMask/metamask-sdk/',
},
{
label: 'MetaMask Mobile GitHub',
label: 'MetaMask mobile GitHub',
href: 'https://github.com/MetaMask/metamask-mobile',
},
{
2 changes: 1 addition & 1 deletion sdk/connect/javascript-dynamic.md
Original file line number Diff line number Diff line change
@@ -271,4 +271,4 @@ Common issues and solutions include:
- **Mobile experience issues:**
- Test on actual mobile devices.
- Verify redirect URLs.
- Check MetaMask Mobile installation.
- Check MetaMask mobile app installation.
16 changes: 8 additions & 8 deletions sdk/guides/use-deeplinks.md
Original file line number Diff line number Diff line change
@@ -8,13 +8,13 @@ import TabItem from "@theme/TabItem";

# Use deeplinks

You can use deeplinks to directly route your users to specific, pre-configured functions inside the MetaMask Mobile app.
You can use deeplinks to directly route your users to specific, pre-configured functions inside the MetaMask mobile app.
For example, you can create a deeplink that lets users make one-click payments with a preset token, recipient, and amount.
You can also convert deeplinks to QR codes, so users can scan them with a mobile device.

If a user doesn't have MetaMask Mobile installed, deeplinks route the user to a landing page where they can download the app.
If a user doesn't have the mobile app installed, deeplinks route the user to a landing page where they can download the app.

This page highlights deeplinks available for MetaMask Mobile.
This page highlights deeplinks available for the MetaMask mobile app.

## Open a dapp inside the in-app browser

@@ -36,7 +36,7 @@ https://metamask.app.link/dapp/app.uniswap.org
</Tabs>


This deeplink takes the user directly to the dapp URL in the MetaMask Mobile in-app browser.
This deeplink takes the user directly to the dapp URL in the MetaMask mobile in-app browser.

The example navigates to `app.uniswap.org` in the in-app browser.

@@ -64,7 +64,7 @@ https://metamask.app.link/send/0x0000000@137?value=1e16
</Tabs>

This deeplink starts the process of sending a transaction in the native currency.
If the chain ID is specified, MetaMask Mobile automatically switches to the correct network.
If the chain ID is specified, the MetaMask mobile app automatically switches to the correct network.

The example displays the confirmation screen to send 0.01 POL (`1e16` wei) in Polygon (chain ID `137`) to recipient address `0x0000000`.

@@ -97,7 +97,7 @@ https://metamask.app.link/send/0x176211869cA2b568f2A7D4EE941E073a821EE1ff@59144/
</Tabs>

This deeplink starts the process of sending a transaction in an ERC-20 token.
If the chain ID is specified, MetaMask Mobile automatically switches to the correct network.
If the chain ID is specified, the MetaMask mobile app automatically switches to the correct network.

The example displays the confirmation screen to send 1 USDC (`1e6` units, contract address `0x176211869cA2b568f2A7D4EE941E073a821EE1ff`) on Linea (chain ID `59144`) to recipient address `0x0000000`.

@@ -131,7 +131,7 @@ https://metamask.app.link/buy?chainId=59144&address=0x176211869cA2b568f2A7D4EE94
</Tabs>

This deeplink starts the on-ramp process to buy native currency or ERC-20 tokens.
If the chain ID is specified, MetaMask Mobile automatically switches to the correct network.
If the chain ID is specified, the MetaMask mobile app automatically switches to the correct network.

The example starts the on-ramp process to buy $100 (`amount=100`) of USDC (contract address `0x176211869cA2b568f2A7D4EE941E073a821EE1ff`) on Linea (chain ID `59144`).
The fiat currency depends on the onboarding status of the user and the region they select.
@@ -167,7 +167,7 @@ https://metamask.app.link/sell?chainId=59144&amount=125
</Tabs>

This deeplink starts the off-ramp process to sell native currency.
If the chain ID is specified, MetaMask Mobile automatically switches to the correct network.
If the chain ID is specified, the MetaMask mobile app automatically switches to the correct network.

The example starts the off-ramp process to sell 125 ETH (`amount=125`) on Linea (chain ID `59144`).

7 changes: 4 additions & 3 deletions sdk/index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
slug: /
title: SDK introduction
description: Introduction page for MetaMask SDK documentation.
keywords: [connect, MetaMask, SDK, integrate, dapp]
---
@@ -9,7 +10,7 @@ import CardList from '@site/src/components/CardList'

# Seamlessly connect to MetaMask using the SDK

MetaMask SDK enables a fast, reliable, and seamless connection from your dapp to the MetaMask extension and MetaMask Mobile.
MetaMask SDK enables a fast, reliable, and seamless connection from your dapp to the MetaMask extension and MetaMask mobile app.
With the SDK, you can easily onboard users and interact with their accounts on desktop or mobile, across all EVM networks.

<p align="center">
@@ -29,9 +30,9 @@ With the SDK, you can easily onboard users and interact with their accounts on d

MetaMask SDK gives your dapp a powerful upgrade:

- **Cross-platform, cross-browser support** - One integration covers both desktop and mobile, all major browsers, and the MetaMask Mobile app—streamlining your user onboarding and eliminating edge cases.
- **Cross-platform, cross-browser support** - One integration covers both desktop and mobile, all major browsers, and the MetaMask mobile app—streamlining your user onboarding and eliminating edge cases.
- **Mobile connection that just works** - Say goodbye to clunky "open in in-app browser" flows.
The SDK enables a native connection from any mobile browser (Safari, Chrome, etc.) directly to MetaMask Mobile, using secure deeplinking and session management.
The SDK enables a native connection from any mobile browser (Safari, Chrome, etc.) directly to the MetaMask mobile app, using secure deeplinking and session management.
- **Production-ready, battle-tested** - MetaMask SDK is used in high-volume dapps across DeFi, NFTs, gaming, and more—ensuring stability, speed, and a smooth developer experience.
- **Multichain-ready by design** - Today, the SDK supports all EVM networks.
Coming soon: Seamless connection to non-EVM chains like Solana and Bitcoin.
8 changes: 4 additions & 4 deletions sdk/reference/sdk-options.md
Original file line number Diff line number Diff line change
@@ -114,9 +114,9 @@ The metadata options are:
- `iconUrl` - URL of the dapp's icon

:::tip important
Setting `dappMetaData` creates a clear and trustworthy user experience when connecting your dapp to
MetaMask Mobile.
MetaMask Mobile displays this metadata in the connection modal to help users identify and verify the
Setting `dappMetaData` creates a clear and trustworthy user experience when connecting your dapp to the
MetaMask mobile app.
MetaMask displays this metadata in the connection modal to help users identify and verify the
connection request.
:::

@@ -262,7 +262,7 @@ openDeeplink: (link: string) => {
</TabItem>
</Tabs>

A function that is called to open a deeplink to the MetaMask Mobile app.
A function that is called to open a deeplink to the MetaMask mobile app.

### `readonlyRPCMap`

4 changes: 2 additions & 2 deletions sdk/reference/supported-platforms.md
Original file line number Diff line number Diff line change
@@ -6,9 +6,9 @@ description: Supported dapp platforms for MetaMask SDK.

With MetaMask SDK, you can connect your dapp to MetaMask in the following ways:

- **Desktop web dapps** - Automatically connect to the MetaMask wallet extension, or connect to MetaMask Mobile using a QR code.
- **Desktop web dapps** - Automatically connect to the MetaMask extension, or connect to the MetaMask mobile app using a QR code.

- **Mobile dapps** - The SDK generates a deeplink that takes users directly to MetaMask Mobile.
- **Mobile dapps** - The SDK generates a deeplink that takes users directly to the MetaMask mobile app.

The following table expands on the SDK's connection methods:

1 change: 1 addition & 0 deletions services/index.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
---
title: Services introduction
sidebar_label: Introduction
sidebar_position: 1
---
7 changes: 5 additions & 2 deletions snaps/index.mdx
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
---
sidebar_label: Introduction
title: Snaps introduction
description: Introduction page for the MetaMask Snaps documentation.
---

import CardList from '@site/src/components/CardList'
import YoutubeEmbed from '@site/src/components/YoutubeEmbed'

# Extend the functionality of MetaMask using Snaps
# Create a custom mini app using Snaps

Snaps is an open source system that allows anyone to safely extend the functionality of [MetaMask](https://metamask.io/), creating new web3 end user experiences. Get started building your own Snaps by [installing MetaMask Flask](get-started/install-flask.md).
Snaps is an open source system that allows anyone to safely create a mini app that runs inside the MetaMask extension,
enabling new web3 end user experiences.
Get started building your own Snaps by [installing MetaMask Flask](get-started/install-flask.md).

## What can you do with a Snap?

4 changes: 2 additions & 2 deletions snaps/learn/about-snaps/index.md
Original file line number Diff line number Diff line change
@@ -5,8 +5,8 @@

# About Snaps

MetaMask Snaps is an open source system that allows anyone to safely extend the functionality of
MetaMask, creating new web3 end user experiences.
MetaMask Snaps is an open source system that allows anyone to safely create a mini app that runs inside the MetaMask extension,

Check warning on line 8 in snaps/learn/about-snaps/index.md

GitHub Actions / Spelling (.mdx)

[vale] reported by reviewdog 🐶 [Microsoft.Adverbs] Remove 'safely' if it's not important to the meaning of the statement. Raw Output: {"message": "[Microsoft.Adverbs] Remove 'safely' if it's not important to the meaning of the statement.", "location": {"path": "snaps/learn/about-snaps/index.md", "range": {"start": {"line": 8, "column": 63}}}, "severity": "WARNING"}

Check warning on line 8 in snaps/learn/about-snaps/index.md

GitHub Actions / Spelling (.md)

[vale] reported by reviewdog 🐶 [Microsoft.Adverbs] Remove 'safely' if it's not important to the meaning of the statement. Raw Output: {"message": "[Microsoft.Adverbs] Remove 'safely' if it's not important to the meaning of the statement.", "location": {"path": "snaps/learn/about-snaps/index.md", "range": {"start": {"line": 8, "column": 63}}}, "severity": "WARNING"}
enabling new web3 end user experiences.
For example, a Snap can add support for different blockchain networks, add custom account types, or
provide additional functionality using its own APIs.
This allows MetaMask to be used with a far more diverse set of protocols, dapps, and services.
6 changes: 3 additions & 3 deletions src/components/CallToAction/CallToAction.module.scss
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
.call-to-action {
position: relative;
padding: 1.5rem 0 6.4rem;
padding: 2rem 0 6.4rem;
overflow: hidden;

@include bp(tablet) {
padding-top: 2rem;
padding-top: 4rem;
}

@include bp(desktop) {
padding: 3rem 0 8rem;
padding: 5rem 0 8rem;
}
}

9 changes: 5 additions & 4 deletions src/components/Card.tsx
Original file line number Diff line number Diff line change
@@ -15,13 +15,14 @@ export type CardItem = {
href: string
description?: string | ReactNode
theme?: string
buttonIcon?: 'arrow-right' | 'external-arrow'
}

export default function Card({ title, href, description, theme }: CardItem) {
export default function Card({ title, href, description, theme, buttonIcon = "arrow-right" }: CardItem) {
const [isHovered, setIsHovered] = useState(false)

return (
<li className={clsx(styles['item'], isHovered && styles['active'])}>
<div className={clsx(styles['item'], isHovered && styles['active'])}>
<CutOffCorners size="s">
<div
className={styles['holder']}
@@ -49,7 +50,7 @@ export default function Card({ title, href, description, theme }: CardItem) {
as="button"
label={false}
type={theme === 'dark' ? 'secondary' : 'primary'}
icon="arrow-right"
icon={buttonIcon}
className={styles['button']}
style={
theme === 'dark'
@@ -68,6 +69,6 @@ export default function Card({ title, href, description, theme }: CardItem) {
</Link>
</div>
</CutOffCorners>
</li>
</div>
)
}
68 changes: 60 additions & 8 deletions src/components/CardSection.module.scss
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
.wrapper {
position: relative;
padding: 2rem 0 0;
overflow: hidden;
padding: 2rem 0 2rem;
overflow: visible;

@include bp(tablet) {
padding-top: 3rem;
padding-top: 3rem 0 3rem;
}

@include bp(desktop) {
padding: 4rem 0 0;
padding: 4rem 0 4rem;
}
}

@@ -35,7 +35,25 @@
}
}

.grid {
.section-grid {
display: flex;
flex-direction: column;
gap: 2rem;

@include bp('desktop') {
display: grid;
grid-template-columns: 1fr 2fr;
gap: 4rem;
align-items: start;
}
}

.content-column {
display: flex;
flex-direction: column;
}

.cards-wrapper {
display: grid;
grid-template-columns: 1fr;
gap: 2rem;
@@ -45,8 +63,42 @@
}
}

.grid > li {
&:last-child {
margin-bottom: 1.6rem;
.card-column {
display: flex;
}

.header {
margin-bottom: 0;

h2 {
font-size: 2.4rem;
font-weight: 500;
margin: 0 0 2rem 0;
color: var(--color-text-heading);
line-height: 1.2;

@include bp(tablet) {
font-size: 2.8rem;
}

@include bp(desktop) {
font-size: 3.2rem;
}
}

p {
font-size: 1.6rem;
font-weight: 400;
margin: 0;
color: var(--color-text-paragraph);
line-height: 1.5;

@include bp(tablet) {
font-size: 1.7rem;
}

@include bp(desktop) {
font-size: 1.8rem;
}
}
}
52 changes: 36 additions & 16 deletions src/components/CardSection.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import clsx from 'clsx'
import { CSSProperties, JSX, useState, useEffect } from 'react'
import { useColorMode } from '@docusaurus/theme-common'
import Heading from '@theme/Heading'
import Card, { CardItem } from '@site/src/components/Card'

import styles from './CardSection.module.scss'

type CardSectionProps = {
title?: string
description?: string
cards: CardItem[]
colorPalette: string
colorPalette?: string
}

export default function CardSection({ cards, colorPalette }: CardSectionProps): JSX.Element {
export default function CardSection({
title,
description,
cards,
colorPalette,
}: CardSectionProps): JSX.Element {
const { colorMode } = useColorMode()
const [theme, setTheme] = useState('')

@@ -20,12 +26,12 @@ export default function CardSection({ cards, colorPalette }: CardSectionProps):
}, [colorMode])

return (
<section className={styles['wrapper']}>
<section className={styles.wrapper}>
<div className="container">
<div className={styles['grid-wrapper']}>
<div className={styles['grid-col-center']}>
<ul
className={styles['grid']}
<div
className={styles['section-grid']}
style={
colorPalette
? ({
@@ -34,17 +40,31 @@ export default function CardSection({ cards, colorPalette }: CardSectionProps):
: {}
}
>
{cards?.length > 0 &&
cards.map(({ title, description, href }: CardItem, cardIndex: number) => (
<Card
key={cardIndex}
title={title}
description={description}
href={href}
theme={theme}
/>
{/* Title and Description Column */}
{(title || description) && (
<div className={styles['content-column']}>
<div className={styles.header}>
{title && <h2>{title}</h2>}
{description && <p>{description}</p>}
</div>
</div>
)}

{/* Cards Columns */}
<div className={styles['cards-wrapper']}>
{cards.map(({ title, description, href, buttonIcon }, index) => (
<div key={index} className={styles['card-column']}>
<Card
title={title}
description={description}
href={href}
theme={theme}
buttonIcon={buttonIcon}
/>
</div>
))}
</ul>
</div>
</div>
</div>
</div>
</div>
35 changes: 35 additions & 0 deletions src/components/NavDropdown/ConnectMetaMask.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<span class="nav-dropdown-menu">
<ul>
<li>
<a href="/sdk/">
<span>
<svg class="svg-inline--fa fa-rocket fa-w-16 text-text-alternative group-hover:text-text-default" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewBox="0 0 512 512" role="img">
<path fill="currentColor" d="M188.9 372l-50.4-50.4c18.6-42.7 61.7-137.7 95.1-187C304.6 30.1 409 24.6 475.7 36.3c11.7 66.7 6.2 171.1-98.4 242c-49.4 33.5-145.5 75.6-188.4 93.7zm-79.9-62.8c-5.2 11.9-2.5 25.7 6.7 34.9l50.7 50.7c9.1 9.1 22.7 11.9 34.5 6.9c6.5-2.7 14.3-6 23-9.8L224 496c0 5.5 2.9 10.7 7.6 13.6s10.6 3.2 15.6 .7l101.5-50.7c21.7-10.8 35.4-33 35.4-57.2l0-90.2c4-2.5 7.7-4.9 11.3-7.3C516.1 222.9 520.1 100.9 506.7 28.1c-2.1-11.6-11.2-20.6-22.8-22.8C411.1-8.1 289.1-4.1 207.2 116.7c-2.4 3.6-4.9 7.3-7.3 11.3l-90.2 0c-24.2 0-46.4 13.7-57.2 35.4L1.7 264.8c-2.5 5-2.2 10.9 .7 15.6s8.1 7.6 13.6 7.6l102.5 0c-3.6 8-6.8 15.2-9.4 21.2zM256 470.1l0-92.5c30.3-13.7 65.4-30.3 96-47l0 71.7c0 12.1-6.8 23.2-17.7 28.6L256 470.1zM109.7 160l71.5 0c-16.9 30.7-34 65.8-48.1 96l-91.2 0L81 177.7c5.4-10.8 16.5-17.7 28.6-17.7zM392 144a24 24 0 1 1 -48 0 24 24 0 1 1 48 0zM368 88a56 56 0 1 0 0 112 56 56 0 1 0 0-112z">
</path>
</svg>
</span>
<div>
<h2>MetaMask SDK</h2>
<p>Seamlessly connect to MetaMask extension and mobile.</p>
</div>
</a>
</li>
<li>
<a href="/wallet/">
<span>
<svg width="800px" height="800px" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="48" height="48" fill="white" fill-opacity="0.01"/>
<path d="M18 23.9372V10C18 6.68629 20.6863 4 24 4C27.3137 4 30 6.68629 30 10V12.0057" stroke="currentColor" stroke-width="4" stroke-linecap="round"/>
<path d="M30 24.0035V38C30 41.3137 27.3137 44 24 44C20.6863 44 18 41.3137 18 38V35.97" stroke="currentColor" stroke-width="4" stroke-linecap="round"/>
<path d="M24 30H9.98415C6.67919 30 4 27.3137 4 24C4 20.6863 6.67919 18 9.98415 18H11.9886" stroke="currentColor" stroke-width="4" stroke-linecap="round"/>
<path d="M24 18H37.9888C41.3087 18 44 20.6863 44 24C44 27.3137 41.3087 30 37.9888 30H36.0663" stroke="currentColor" stroke-width="4" stroke-linecap="round"/>
</svg>
</span>
<div>
<h2>Wallet API</h2>
<p>Directly integrate your dapp with the MetaMask extension.</p>
</div>
</a>
</li>
</ul>
</span>
2 changes: 1 addition & 1 deletion src/components/NavDropdown/DeveloperTools.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<span class="resources-dropdown-menu">
<span class="nav-dropdown-menu">
<ul>
<li>
<a href="/developer-tools/dashboard/">
38 changes: 38 additions & 0 deletions src/components/NavDropdown/EmbedMetaMask.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<span class="nav-dropdown-menu">
<ul>
<li>
<a href="/delegation-toolkit/">
<span>
<svg class="svg-inline--fa fa-screwdriver-wrench fa-w-16 text-text-alternative group-hover:text-text-default" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewBox="0 0 512 512" role="img">
<path fill="currentColor" d="M64.7 34.6L160 107.9l0 52.1-52.1 0L34.6 64.7 64.7 34.6zM192 169.3c0-.4 0-.9 0-1.3l0-64c0-7.5-3.5-14.5-9.4-19L78.6 5C69.1-2.4 55.6-1.5 47 7L7 47c-8.5 8.5-9.4 22-2.1 31.6l80 104c4.5 5.9 11.6 9.4 19 9.4l64 0c.4 0 .9 0 1.3 0L271.2 293.9c-19.5 30-16.2 70.5 10.1 96.8l112 112c12.5 12.5 32.8 12.5 45.3 0l64-64c12.5-12.5 12.5-32.8 0-45.3l-112-112c-26.3-26.3-66.8-29.7-96.8-10.1L192 169.3zM304 304c17.7-17.7 46.3-17.7 64 0L480 416l-64 64L304 368c-17.7-17.7-17.7-46.3 0-64zM104 424a16 16 0 1 0 -32 0 16 16 0 1 0 32 0zM23.2 376.8C8.3 391.7 0 411.8 0 432.8C0 476.5 35.5 512 79.2 512c21 0 41.1-8.3 56-23.2L238.5 385.5c-5.7-11.2-9.3-23.1-10.9-35.3L112.1 465.7c-8.7 8.7-20.6 13.6-32.9 13.6c-25.7 0-46.6-20.8-46.6-46.6c0-12.3 4.9-24.2 13.6-32.9L189.1 257l-23.1-23.1L23.2 376.8zM479.4 160c0 44.8-23.1 84.1-58 106.8l23.5 23.5c40.7-29 67.2-76.6 67.2-130.3c0-24.8-5.7-48.3-15.7-69.3c-4.4-9.2-16.5-10.5-23.7-3.3l-67.9 67.9c-3 3-7.1 4.7-11.3 4.7L368 160c-8.8 0-16-7.2-16-16l0-25.4c0-4.2 1.7-8.3 4.7-11.3l67.9-67.9c7.2-7.2 5.9-19.3-3.3-23.7C400.3 5.7 376.8 0 352 0C296.1 0 246.9 28.6 218.3 72.1l26 20C266.8 56.3 306.7 32.6 352 32.6c10.3 0 20.2 1.2 29.7 3.5L333.6 84.2c-9.1 9.1-14.2 21.5-14.2 34.4l0 25.4c0 26.9 21.8 48.6 48.6 48.6l25.4 0c12.9 0 25.3-5.1 34.4-14.2l48.1-48.1c2.3 9.5 3.5 19.5 3.5 29.7z">
</path>
</svg>
</span>
<div>
<h2>Delegation Toolkit</h2>
<p>Embed MetaMask smart accounts with new capabilities into your dapp.</p>
</div>
</a>
</li>
<li>
<a href="https://web3auth.io/docs" target="_blank">
<span>
<svg xmlns="http://www.w3.org/2000/svg" data-name="Layer 2" viewBox="0 0 72 72">
<path fill="currentColor" d="M54.249 37.81a2.917 2.917 0 1 0-.001-5.833 2.917 2.917 0 0 0 .001 5.833"></path>
<path fill="currentColor" d="M61.168 54.481a2.587 2.587 0 0 1-2.58 2.58H8.336a2.587 2.587 0 0 1-2.58-2.58V7.508a2.59 2.59 0 0 1 2.58-2.58l48.273-.006a2.59 2.59 0 0 1 2.58 2.58v.188a7 7 0 0 0-.841-.045l-45.511.006a.993.993 0 0 0-.989.989v4.093h45.686a3.683 3.683 0 0 1 3.673 3.673v1.882h4.966v-2.819c0-2.716-1.403-5.121-3.524-6.525v-1.28c0-4.301-3.518-7.67-7.818-7.664l-4.21.007-31.945.006H7.23c-3.905 0-7.1 3.194-7.1 7.1v48.305c0 3.893 3.188 7.081 7.081 7.087h51.861c3.557 0 7.158-2.722 7.178-6.098h.013v-4.882h-5.096v2.955Z"></path>
<path fill="currentColor" d="M67.595 21.314H49.657c-7.424 0-13.489 6.072-13.489 13.489s6.072 13.489 13.489 13.489h17.938a4.44 4.44 0 0 0 4.423-4.423V25.737a4.44 4.44 0 0 0-4.423-4.423M66.25 43.358H50.336c-4.701 0-8.549-3.848-8.549-8.549s3.848-8.549 8.549-8.549H66.25z"></path>
</svg>
</span>
<div>
<h2>
Embedded Wallets SDK
<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU">
<path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path>
</svg>
</h2>
<p>Onboard users in seconds via social logins, passkeys, or custom authentication providers.</p>
</div>
</a>
</li>
</ul>
</span>
38 changes: 38 additions & 0 deletions src/components/NavDropdown/ExtendScale.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<span class="nav-dropdown-menu">
<ul>
<li>
<a href="/snaps/">
<span>
<svg width="800px" height="800px" viewBox="0 -0.5 21 21" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Dribbble-Light-Preview" transform="translate(-379.000000, -280.000000)" fill="currentColor">
<g id="icons" transform="translate(56.000000, 160.000000)">
<path d="M341.9,137.261 C341.9,137.811 341.49785,138 340.92035,138 L331.47035,138 C330.89285,138 330.35,137.811 330.35,137.261 L330.35,135 L337.24535,135 C338.11475,135 338.75,134.589 338.75,133.761 L338.75,127 L340.92035,127 C341.49995,127 341.9,127.709 341.9,128.261 L341.9,137.261 Z M326.22035,133 C325.64285,133 325.1,132.811 325.1,132.261 L325.1,123.261 C325.1,122.709 325.6397,122 326.22035,122 L335.67035,122 C336.24995,122 336.65,122.709 336.65,123.261 L336.65,132.261 C336.65,132.811 336.24785,133 335.67035,133 L326.22035,133 Z M342.49535,125 L338.75,125 L338.75,121.761 C338.75,120.933 338.11475,120 337.24535,120 L324.64535,120 C323.7791,120 323,120.936 323,121.761 L323,133.761 C323,134.586 323.7791,135 324.64535,135 L328.25,135 L328.25,138.761 C328.25,139.586 329.0291,140 329.89535,140 L342.49535,140 C343.36475,140 344,139.589 344,138.761 L344,126.761 C344,125.933 343.36475,125 342.49535,125 L342.49535,125 Z" id="new_tab-[#1502]">
</path>
</g>
</g>
</g>
</svg>
</span>
<div>
<h2>Snaps</h2>
<p>Create a custom mini app that runs inside the MetaMask extension.</p>
</div>
</a>
</li>
<li>
<a href="/services/">
<span>
<svg class="svg-inline--fa fa-iconInfuraNode fa-w-19 text-text-alternative group-hover:text-text-default" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewBox="0 0 16 14" role="img">
<path fill="currentColor" d="M0.46624 0.213623V2.27922L5.40032 1.77074H7.22144V5.1141L4.15488 6.05202L0 7.05394L0.61696 9.07346L4.5984 7.54322L7.22144 6.74162V12.2296H5.40032L0.46624 11.7208V13.7864H15.5338V11.7208L10.5997 12.2296H8.77856V6.74162L11.3885 7.53906L15.3834 9.07346L16 7.05394L11.8563 6.0549L8.77856 5.1141V1.77074H10.5997L15.5338 2.27922V0.213623H0.46624Z">
</path>
</svg>
</span>
<div>
<h2>Services</h2>
<p>Use high performance APIs provided by Infura to scale your dapp or Snap.</p>
</div>
</a>
</li>
</ul>
</span>
86 changes: 86 additions & 0 deletions src/components/ProductBanner/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import React, {type ReactNode, useEffect, useState} from 'react';
import {useLocation} from '@docusaurus/router';
import {useThemeConfig} from '@docusaurus/theme-common';
import clsx from 'clsx';
import styles from './styles.module.scss';

interface ProductConfig {
name: string;
description: string;
}

const PRODUCT_CONFIGS: Record<string, ProductConfig> = {
'/sdk/': {
name: 'MetaMask SDK documentation',
description: 'Seamlessly connect to the MetaMask extension and mobile app.',
},
'/wallet/': {
name: 'Wallet API documentation',
description: 'Directly integrate your dapp with the MetaMask extension.',
},
'/delegation-toolkit/': {
name: 'Delegation Toolkit documentation',
description: 'Embed MetaMask smart accounts with new capabilities into your dapp.',
},
'/snaps/': {
name: 'Snaps documentation',
description: 'Create a custom mini app that runs inside the MetaMask extension.',
},
'/services/': {
name: 'Services documentation',
description: 'Use high performance APIs provided by Infura to scale your dapp or Snap.',
},
'/developer-tools/dashboard/': {
name: 'Developer dashboard documentation',
description: 'Manage Infura API keys, monitor usage, and access account details.',
},
};

function getProductConfig(pathname: string): ProductConfig | null {
for (const [path, config] of Object.entries(PRODUCT_CONFIGS)) {
if (pathname.startsWith(path)) {
return config;
}
}
return null;
}

export default function ProductBanner(): ReactNode | null {
const location = useLocation();
const productConfig = getProductConfig(location.pathname);
const {navbar} = useThemeConfig();
const [isNavbarPresent, setIsNavbarPresent] = useState(true);

useEffect(() => {
if (!navbar.hideOnScroll) return;

const checkNavbarPresence = () => {
const navbarElement = document.querySelector('.navbar');
setIsNavbarPresent(!!navbarElement);
};

checkNavbarPresence();
const intervalId = setInterval(checkNavbarPresence, 100);

return () => clearInterval(intervalId);
}, [navbar.hideOnScroll]);


if (!productConfig) {
return null;
}

return (
<div
className={clsx(
styles.productBanner,
!isNavbarPresent && styles.productBannerNoNavbar
)}
>
<div className={styles.productBannerContent}>
<h2 className={styles.productName}>{productConfig.name}</h2>
<p className={styles.productDescription}>{productConfig.description}</p>
</div>
</div>
);
}
39 changes: 39 additions & 0 deletions src/components/ProductBanner/styles.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
.productBanner {
background-color: var(--ifm-navbar-background-color);
padding: 1rem 0;
border-bottom: 1px solid var(--ifm-toc-border-color);
position: sticky;
top: 0;
z-index: 9;
}

.productBannerNoNavbar {
box-shadow: var(--ifm-navbar-shadow);
z-index: 10;
}

.productBannerContent {
font-family: var(--ifm-font-family-base);
color: var(--ifm-navbar-color);
padding: 0.6rem 2.4rem;
position: relative;
text-align: left;
}

.productName {
margin-bottom: 0.5rem;
font-size: 2.2rem;
font-weight: 500;
}

.productDescription {
margin: 0;
font-size: 1.6rem;
}

/* Hide in mobile view */
@media (max-width: 768px) {
.productBanner {
display: none;
}
}
50 changes: 50 additions & 0 deletions src/components/SectionIntro/SectionIntro.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
.wrapper {
position: relative;
padding: 2rem 0 0;
overflow: hidden;

@include bp(tablet) {
padding-top: 3rem;
}

@include bp(desktop) {
padding: 4rem 0 0;
}
}

.grid-wrapper {
@include bp('tablet') {
@include grid;
}
}

.grid-col-center {
position: relative;

@include bp('tablet') {
@include grid-column-span(8);
}

@include bp('desktop') {
@include grid-column-span(14);
@include grid-column-start(2);
}
}

.header {
margin-bottom: 1rem;

h2 {
font-size: 1.8rem;
font-weight: 600;
margin: 0;
color: var(--color-text-heading);
}

p {
font-size: 1.8rem;
font-weight: 500;
margin: 0.5rem 0 0;
color: var(--color-text-paragraph);
}
}
18 changes: 18 additions & 0 deletions src/components/SectionIntro/SectionIntro.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import clsx from 'clsx'
import styles from './SectionIntro.module.scss'

export default function SectionIntro({ description }: { description: string }) {
return (
<section className={styles.wrapper}>
<div className="container">
<div className={styles['grid-wrapper']}>
<div className={styles['grid-col-center']}>
<div className={styles.header}>
<p>{description}</p>
</div>
</div>
</div>
</div>
</section>
)
}
58 changes: 58 additions & 0 deletions src/hooks/useCustomHideableNavbar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import {useCallback, useEffect, useRef, useState} from 'react';
import {useLocationChange} from '@docusaurus/theme-common/internal';

const useCustomHideableNavbar = (hideOnScroll: boolean) => {
const [isNavbarVisible, setIsNavbarVisible] = useState(true);
const navbarRef = useRef<HTMLElement>(null);
const lastScrollTop = useRef(0);

const handleScroll = useCallback(() => {
if (!hideOnScroll) {
return;
}

const currentScrollTop = window.pageYOffset || document.documentElement.scrollTop;
const scrollingUp = currentScrollTop < lastScrollTop.current;
const scrollDifference = Math.abs(currentScrollTop - lastScrollTop.current);

// Show navbar when at the top or scrolling up
if (currentScrollTop <= 5 || scrollingUp) {
setIsNavbarVisible(true);
}
// Hide only when scrolling down significantly and past a larger threshold
else if (currentScrollTop > 100 && scrollDifference > 20) {
setIsNavbarVisible(false);
}

lastScrollTop.current = currentScrollTop;
}, [hideOnScroll]);

useLocationChange((locationChangeEvent) => {
if (!hideOnScroll) {
return;
}
setIsNavbarVisible(true);
lastScrollTop.current = 0;
});

useEffect(() => {
if (!hideOnScroll) {
return undefined;
}

window.addEventListener('scroll', handleScroll, {
passive: true,
});

return () => {
window.removeEventListener('scroll', handleScroll);
};
}, [handleScroll, hideOnScroll]);

return {
navbarRef,
isNavbarVisible,
};
};

export default useCustomHideableNavbar;
54 changes: 38 additions & 16 deletions src/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -2,71 +2,93 @@ import Layout from '@theme/Layout'
import Hero from '@site/src/components/Hero/Hero'
import CardSection from '@site/src/components/CardSection'
import CallToAction from '@site/src/components/CallToAction/CallToAction'
import SectionIntro from '@site/src/components/SectionIntro/SectionIntro'
import useDocusaurusContext from '@docusaurus/useDocusaurusContext'

export default function Home(): JSX.Element {
const { siteConfig } = useDocusaurusContext()

return (
<Layout title={'Home'}>
<Layout title="Home">
<Hero
title={siteConfig.title}
description={"Build with the world's leading self-custodial crypto wallet."}
description="Build with the world's leading self-custodial crypto wallet."
button={{
label: 'Get Started',
href: '/sdk',
icon: 'arrow-right',
}}
/>
<SectionIntro description="What do you want to build with MetaMask? Whether you're integrating with the extension, embedding smart wallets, or scaling with powerful infrastructure—choose a path below to get started." />
<CardSection
title="Connect to MetaMask extension and mobile"
description="Connect your dapp to the MetaMask browser extension and MetaMask mobile app. Ideal for users who want full control over their keys and transactions."
colorPalette="purple"
cards={[
{
title: 'MetaMask SDK',
description:
'Use MetaMask SDK to provide your users a fast, reliable, and seamless connection to the MetaMask extension and MetaMask Mobile.',
'Provide your users a fast, reliable, and seamless connection to MetaMask extension and mobile.',
href: '/sdk',
theme: '',
buttonIcon: "arrow-right",
},
{
title: 'Wallet API',
description:
"Use the Wallet API to directly integrate your dapp with the MetaMask browser extension, and interact with your users' accounts.",
"Directly integrate your dapp with the MetaMask extension, and interact with your users' accounts.",
href: '/wallet',
theme: '',
buttonIcon: "arrow-right",
},
]}
/>

<CardSection
title="Add an embedded MetaMask wallet"
description="Enable embedded wallets and smart accounts directly within your dapp. Ideal for seamless onboarding, custom permission controls, and mobile-first, or first-time user experiences."
colorPalette="purple"
cards={[
{
title: 'Delegation Toolkit',
description:
'Integrate MetaMask smart accounts into your dapp. Create embedded wallets that support delegated permissions, gas abstraction, and secure execution.',
href: '/delegation-toolkit',
buttonIcon: "arrow-right",
},
{
title: 'Embedded Wallets SDK',
description:
'Use the Embedded Wallets SDK (Web3Auth) to onboard power users and first-time users in seconds via social logins, passkeys, or by integrating your own authentication providers.',
href: 'https://web3auth.io/docs',
'Onboard power users and first-time users in seconds via social logins, passkeys, or by integrating your own authentication providers.',
href: 'https://web3auth.io/docs/',
buttonIcon: "external-arrow",
},
]}
/>

<CardSection
title="Extend MetaMask and scale your dapp"
description="Extend MetaMask's capabilities and build scalable dapps with developer tools, hosted infrastructure, and customizable Snaps."
colorPalette="purple"
cards={[
{
title: 'Snaps',
description:
'Create a custom Snap to extend the functionality of MetaMask. Add support for custom networks, accounts types, and APIs.',
'Create a custom mini app that runs inside the MetaMask extension. Add support for custom networks, accounts types, and APIs.',
href: '/snaps',
theme: '',
buttonIcon: "arrow-right",
},
{
title: 'Services',
description:
'Use services provided by MetaMask and Infura to optimize essential development tasks and scale your dapp or Snap.',
'Use high performance APIs provided by MetaMask and Infura to build and scale your dapp or Snap.',
href: '/services',
theme: '',
buttonIcon: "arrow-right",
},
]}
/>

<CallToAction
title={'Contribute to MetaMask on GitHub'}
description={
'Join the MetaMask developer community and learn how to contribute to the MetaMask project itself.'
}
title="Contribute to MetaMask on GitHub"
description="Join the MetaMask developer community and learn how to contribute to the MetaMask project itself."
button={{
label: 'Contribute',
href: 'https://github.com/metamask',
63 changes: 52 additions & 11 deletions src/scss/custom.scss
Original file line number Diff line number Diff line change
@@ -306,7 +306,7 @@ ol {
padding: 2rem 0 0;

@include bp('desktop') {
padding: 2.8rem 0 0 8rem;
padding: 2.8rem 0 0 5rem;
}
}

@@ -348,10 +348,25 @@ ol {
}
}

.navbar__brand {
margin-right: 2rem !important;
}

.DocSearch-Button-Placeholder {
font-size: 1.4rem !important;
}

/* Breadcrumbs */

.breadcrumbs {
margin-top: 0 !important;
margin-bottom: 2rem !important;
}

.breadcrumbs__link {
font-size: 1.3rem !important;
}

/* Details */

.details_lb9f > summary {
@@ -652,7 +667,7 @@ ol {
border-left: 3px solid #1aff0080;
}

.resources-dropdown-menu {
.nav-dropdown-menu {
display: flex;
flex-direction: row;
align-items: center;
@@ -676,7 +691,7 @@ ol {
flex-direction: row;
justify-content: flex-start;
align-items: flex-start;
width: 240px;
width: 350px;
padding-left: 0;
margin: 0;
color: var(--ifm-navbar-link-color);
@@ -721,7 +736,7 @@ ol {
svg {
display: inline-block;
vertical-align: top;
width: 24px;
width: 26px;
height: 24px;
color: var(--w3a-color-icon-gray);
transition: color 0.2s ease;
@@ -738,14 +753,15 @@ ol {

h2 {
@extend .dropdown__link;
font-size: 1.6rem !important;
text-decoration: none !important;
margin: 0 0 4px 0;
color: inherit;
}

p {
font-size: 14px;
line-height: 18px;
font-size: 1.4rem;
line-height: 1.8rem;
font-weight: 400 !important;
color: var(--w3a-color-icon-gray);
text-decoration: none !important;
@@ -754,17 +770,17 @@ ol {
}
}

.resources-dropdown-menu a:hover h2 {
.nav-dropdown-menu a:hover h2 {
color: inherit !important;
}

@include bp-max('tablet') {
.resources-dropdown-menu ul {
gap: 16px; // More spacing between items on mobile
.nav-dropdown-menu ul {
gap: 15px;
}

.resources-dropdown-menu a {
width: 100%; // Makes each box take full width of dropdown
.nav-dropdown-menu a {
width: 80%;
}
}

@@ -800,3 +816,28 @@ div[class^='announcementBar_'] {
}
}
}

/* Removes "What's new?" on small viewports to make room for left navbar labels */
@media (max-width: 1196px) {
.navbar__items--right .navbar__item {
display: none;
}

[class*='docMainContainer'],
[class*='mainContainer'] {
padding: 2rem 0 0 2rem;
}
}

/* Fixes bug: Removes sidebar logo appearing on Wallet RPC reference pages */
.sidebar_mhZE .sidebarLogo_F_0z {
display: none !important;
}

.sidebar_mhZE {
padding-top: var(--ifm-navbar-height) !important;
}

.pageWrapper .sidebar_mhZE {
padding-top: 0 !important;
}
31 changes: 31 additions & 0 deletions src/theme/Layout/Provider/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import React, {type ReactNode} from 'react';
import {composeProviders} from '@docusaurus/theme-common';
import {
ColorModeProvider,
AnnouncementBarProvider,
ScrollControllerProvider,
NavbarProvider,
PluginHtmlClassNameProvider,
} from '@docusaurus/theme-common/internal';
import {DocsPreferredVersionContextProvider} from '@docusaurus/plugin-content-docs/client';
import type {Props} from '@theme/Layout/Provider';

const Provider = composeProviders([
ColorModeProvider,
AnnouncementBarProvider,
ScrollControllerProvider,
DocsPreferredVersionContextProvider,
PluginHtmlClassNameProvider,
NavbarProvider,
]);

export default function LayoutProvider({children}: Props): ReactNode {
return <Provider>{children}</Provider>;
}
59 changes: 59 additions & 0 deletions src/theme/Layout/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React, {type ReactNode} from 'react';
import clsx from 'clsx';
import ErrorBoundary from '@docusaurus/ErrorBoundary';
import {
PageMetadata,
SkipToContentFallbackId,
ThemeClassNames,
} from '@docusaurus/theme-common';
import {useKeyboardNavigation} from '@docusaurus/theme-common/internal';
import SkipToContent from '@theme/SkipToContent';
import AnnouncementBar from '@theme/AnnouncementBar';
import Navbar from '@theme/Navbar';
import Footer from '@theme/Footer';
import LayoutProvider from '@theme/Layout/Provider';
import ErrorPageContent from '@theme/ErrorPageContent';
import type {Props} from '@theme/Layout';
import styles from './styles.module.css';
import ProductBanner from '@site/src/components/ProductBanner';

export default function Layout(props: Props): ReactNode {
const {
children,
noFooter,
wrapperClassName,
// Not really layout-related, but kept for convenience/retro-compatibility
title,
description,
} = props;

useKeyboardNavigation();

return (
<LayoutProvider>
<PageMetadata title={title} description={description} />

<SkipToContent />

<AnnouncementBar />

<Navbar />

<ProductBanner />

<div
id={SkipToContentFallbackId}
className={clsx(
ThemeClassNames.wrapper.main,
styles.mainWrapper,
wrapperClassName,
)}>
<ErrorBoundary fallback={(params) => <ErrorPageContent {...params} />}>
{children}
</ErrorBoundary>
</div>

{!noFooter && <Footer />}
</LayoutProvider>
);
}
21 changes: 21 additions & 0 deletions src/theme/Layout/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
html,
body {
height: 100%;
}

.mainWrapper {
flex: 1 0 auto;
display: flex;
flex-direction: column;
}

/* Docusaurus-specific utility class */
:global(.docusaurus-mt-lg) {
margin-top: 3rem;
}

:global(#__docusaurus) {
min-height: 100%;
display: flex;
flex-direction: column;
}
90 changes: 90 additions & 0 deletions src/theme/Navbar/Content/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import React, {type ReactNode} from 'react';
import {useThemeConfig, ErrorCauseBoundary} from '@docusaurus/theme-common';
import {
splitNavbarItems,
useNavbarMobileSidebar,
} from '@docusaurus/theme-common/internal';
import NavbarItem, {type Props as NavbarItemConfig} from '@theme/NavbarItem';
import NavbarColorModeToggle from '@theme/Navbar/ColorModeToggle';
import SearchBar from '@theme/SearchBar';
import NavbarMobileSidebarToggle from '@theme/Navbar/MobileSidebar/Toggle';
import NavbarLogo from '@theme/Navbar/Logo';
import NavbarSearch from '@theme/Navbar/Search';

import styles from './styles.module.css';

function useNavbarItems() {
// TODO temporary casting until ThemeConfig type is improved
return useThemeConfig().navbar.items as NavbarItemConfig[];
}

function NavbarItems({items}: {items: NavbarItemConfig[]}): ReactNode {
return (
<>
{items.map((item, i) => (
<ErrorCauseBoundary
key={i}
onError={(error) =>
new Error(
`A theme navbar item failed to render.
Please double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:
${JSON.stringify(item, null, 2)}`,
{cause: error},
)
}>
<NavbarItem {...item} />
</ErrorCauseBoundary>
))}
</>
);
}

function NavbarContentLayout({
left,
right,
}: {
left: ReactNode;
right: ReactNode;
}) {
return (
<div className="navbar__inner">
<div className="navbar__items">{left}</div>
<div className="navbar__items navbar__items--right">{right}</div>
</div>
);
}

export default function NavbarContent(): ReactNode {
const mobileSidebar = useNavbarMobileSidebar();

const items = useNavbarItems();
const [leftItems, rightItems] = splitNavbarItems(items);

const searchBarItem = items.find((item) => item.type === 'search');

return (
<NavbarContentLayout
left={
// TODO stop hardcoding items?
<>
{!mobileSidebar.disabled && <NavbarMobileSidebarToggle />}
<NavbarLogo />
<NavbarItems items={leftItems} />
</>
}
right={
// TODO stop hardcoding items?
// Ask the user to add the respective navbar items => more flexible
<>
<NavbarItems items={rightItems} />
<NavbarColorModeToggle className={styles.colorModeToggle} />
{!searchBarItem && (
<NavbarSearch>
<SearchBar />
</NavbarSearch>
)}
</>
}
/>
);
}
8 changes: 8 additions & 0 deletions src/theme/Navbar/Content/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
Hide color mode toggle in small viewports
*/
@media (max-width: 1196px) {
.colorModeToggle {
display: none;
}
}
57 changes: 57 additions & 0 deletions src/theme/Navbar/Layout/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React, {type ComponentProps, type ReactNode} from 'react';
import clsx from 'clsx';
import {useThemeConfig} from '@docusaurus/theme-common';
import {useNavbarMobileSidebar} from '@docusaurus/theme-common/internal';
import {translate} from '@docusaurus/Translate';
import NavbarMobileSidebar from '@theme/Navbar/MobileSidebar';
import useCustomHideableNavbar from '@site/src/hooks/useCustomHideableNavbar';
import type {Props} from '@theme/Navbar/Layout';

import styles from './styles.module.css';

function NavbarBackdrop(props: ComponentProps<'div'>) {
return (
<div
role="presentation"
{...props}
className={clsx('navbar-sidebar__backdrop', props.className)}
/>
);
}

export default function NavbarLayout({children}: Props): ReactNode {
const {
navbar: {hideOnScroll, style},
} = useThemeConfig();
const mobileSidebar = useNavbarMobileSidebar();
const {navbarRef, isNavbarVisible} = useCustomHideableNavbar(hideOnScroll);

return (
<div className={styles.navbarContainer}>
<nav
ref={navbarRef}
aria-label={translate({
id: 'theme.NavBar.navAriaLabel',
message: 'Main',
description: 'The ARIA label for the main navigation',
})}
className={clsx(
'navbar',
styles.navbar,
hideOnScroll && [
styles.navbarHideable,
!isNavbarVisible && styles.navbarHidden,
],
{
'navbar--dark': style === 'dark',
'navbar--primary': style === 'primary',
'navbar-sidebar--show': mobileSidebar.shown,
},
)}>
{children}
<NavbarBackdrop onClick={mobileSidebar.toggle} />
<NavbarMobileSidebar />
</nav>
</div>
);
}
15 changes: 15 additions & 0 deletions src/theme/Navbar/Layout/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.navbarContainer {
min-height: var(--ifm-navbar-height);
position: relative;
}

.navbar {
position: relative;
z-index: var(--ifm-z-index-fixed);
width: 100%;
}

.navbarHidden {
visibility: hidden;
pointer-events: none;
}
4 changes: 2 additions & 2 deletions wallet/concepts/convenience-libraries.md
Original file line number Diff line number Diff line change
@@ -17,5 +17,5 @@

You can use [MetaMask SDK](/sdk), which provides a reliable, secure, and
seamless connection from your dapp to MetaMask.
It onboards users smoothly from multiple dapp platforms using the MetaMask browser extension or
MetaMask Mobile, and your dapp can call any [Wallet API](wallet-api.md) methods with the SDK installed.
It onboards users smoothly from multiple dapp platforms using the MetaMask extension or

Check warning on line 20 in wallet/concepts/convenience-libraries.md

GitHub Actions / Spelling (.mdx)

[vale] reported by reviewdog 🐶 [Microsoft.Adverbs] Remove 'smoothly' if it's not important to the meaning of the statement. Raw Output: {"message": "[Microsoft.Adverbs] Remove 'smoothly' if it's not important to the meaning of the statement.", "location": {"path": "wallet/concepts/convenience-libraries.md", "range": {"start": {"line": 20, "column": 19}}}, "severity": "WARNING"}

Check warning on line 20 in wallet/concepts/convenience-libraries.md

GitHub Actions / Spelling (.md)

[vale] reported by reviewdog 🐶 [Microsoft.Adverbs] Remove 'smoothly' if it's not important to the meaning of the statement. Raw Output: {"message": "[Microsoft.Adverbs] Remove 'smoothly' if it's not important to the meaning of the statement.", "location": {"path": "wallet/concepts/convenience-libraries.md", "range": {"start": {"line": 20, "column": 19}}}, "severity": "WARNING"}
mobile app, and your dapp can call any [Wallet API](wallet-api.md) methods with the SDK installed.
11 changes: 6 additions & 5 deletions wallet/how-to/connect-extension.md
Original file line number Diff line number Diff line change
@@ -14,16 +14,17 @@ deeplinking, connect to MetaMask using [**MetaMask SDK**](/sdk) instead.
You can connect your dapp to users' MetaMask wallets by detecting MetaMask in their browsers and
connecting to their accounts.
This page provides instructions for connecting to MetaMask using the wallet detection mechanism
introduced by [EIP-6963](https://eips.ethereum.org/EIPS/eip-6963).
introduced by [EIP-6963](../concepts/wallet-interoperability.md).
This approach allows you to detect multiple installed wallets and connect to them without conflicts.

:::info
Learn more about EIP-6963 in [Wallet interoperability](../concepts/wallet-interoperability.md).
:::

You can connect to the MetaMask browser extension [using third-party libraries](#connect-to-metamask-using-third-party-libraries)
or [directly using Vite](#connect-to-metamask-directly-using-vite).

:::note
Using the Wallet API enables your dapp to work both with the MetaMask extension and in the in-app browser of the MetaMask mobile app.
However, we recommend using the [SDK](/sdk) for a more consistent mobile connection.
:::

## Connect to MetaMask using third-party libraries

You can connect to MetaMask using the following third-party libraries that support EIP-6963:
6 changes: 6 additions & 0 deletions wallet/index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
slug: /
title: Wallet API introduction
description: Introduction page for the Wallet API documentation.
keywords: [extension, api]
---
@@ -34,3 +35,8 @@ If you're building a desktop web-only dapp, the Wallet API provides everything y

[**MetaMask SDK**](/sdk) builds on top of the Wallet API, adding cross-platform support and features like mobile deeplinking and QR code connections.
We recommend the SDK if you want to build a cross-platform onchain dapp.

:::note
Directly using the Wallet API also enables your dapp to work in the in-app browser of the MetaMask mobile app.
However, the [SDK](/sdk) offers a more consistent mobile connection.
:::
2 changes: 1 addition & 1 deletion wallet/reference/json-rpc-methods/index.md
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@ Each method may have one or more of the following labels:

- **MetaMask** - The functionalities of these methods are specific to MetaMask, and may or may not be supported by other wallets.
- **Restricted** - These methods are restricted and require requesting permission using [`wallet_requestPermissions`](/wallet/reference/json-rpc-methods/wallet_requestpermissions).
- **Mobile** - These methods are only available on MetaMask Mobile.
- **Mobile** - These methods are only available on the MetaMask mobile app.
- **Ethereum API** - These are standard Ethereum JSON-RPC API methods. See the [Ethereum wiki](https://ethereum.org/en/#json-rpc-methods) for more information about these methods.
- **Multichain API** - These methods are compatible with the [Multichain API](../multichain-api.md).
- **Experimental** - These methods are experimental and may be changed in the future.