Skip to content

Commit 583083e

Browse files
0618zhamujun
andauthored
feat(docs): change url platform indicator from param to pathname (#1871)
* use platform dynamic path * redirect to react and fix the links * fix: SecondaryNav links * fix meta-info * fix: header and navigation * fix components nav * fix logo button color * add useCustomRouter * fix sitemap by replacing next-sitemap * fix github env * fix github env * seo url path change alt 2 * fix path * fix links * fix url in contents * fix logo link * fix param redirect and header current tab * fix redirection * fix sitemap * fix github test * fix content links * fix header highlight * add "/" and "/[platform]" * add canonical to homepage and react homepage * capitalize title * fix test-prs for github PR * resolve review comments * remove github workflow temporary change * verbiage change * add conanical to all frameworks and fix formats * disallow googlebot for non-Prod env * fix format Co-authored-by: MJ☔ <[email protected]>
1 parent 10b03d9 commit 583083e

File tree

712 files changed

+1028
-820
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

712 files changed

+1028
-820
lines changed

docs/.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
SITE_URL=

docs/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ These docs are published at https://docs.amplify.aws/ui and powered by the follo
1717

1818
### Creating a Page
1919

20-
Page paths mirror their URLs. For example, `/ui/components/authenticator` is located at [/src/pages/ui/components/authenticator/index.page.mdx](src/pages/ui/components/authenticator/index.page.mdx).
20+
Page paths mirror their URLs. For example, `/components/authenticator` is located at [/src/pages/[platform]/components/authenticator/index.page.mdx](src/pages/[platform]/components/authenticator/index.page.mdx).
2121

2222
Component & primitive pages are located at `src/pages/ui/components/*/index.page.mdx` and `src/pages/ui/primitives/*/index.page.mdx`, respectively.
2323

docs/next-sitemap.js

Lines changed: 0 additions & 4 deletions
This file was deleted.

docs/next.config.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,24 @@ module.exports = withNextPluginPreval({
101101
destination: '/theming/:page*',
102102
permanent: false,
103103
},
104+
/**
105+
* source: a url has one of the folder's names (components, getting-started, guides, theming)
106+
* destination: add '[platform]' to the the beginning
107+
*/
108+
{
109+
source: '/:nav(components|getting-started|guides|theming)/:page*',
110+
destination: '/[platform]/:nav/:page*',
111+
permanent: true,
112+
},
113+
/**
114+
* source: a url points one of the folder's names (components, getting-started, guides, theming)'s index file
115+
* destination: add '[platform]' to the beginning
116+
*/
117+
{
118+
source: '/:nav(components|getting-started|guides|theming)',
119+
destination: '/[platform]/:nav',
120+
permanent: true,
121+
},
104122
];
105123
},
106124

docs/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"flutter:copy": "cp -r ./flutter/authenticator/build/web public/flutter/authenticator",
1212
"build": "next build",
1313
"lint": "next lint",
14-
"postbuild": "npx next-sitemap",
14+
"postbuild": "node ./scripts/generate-sitemap-robotstxt.mjs",
1515
"start": "next start",
1616
"test": "$_ run build"
1717
},
@@ -35,7 +35,6 @@
3535
"mdx-prism": "^0.3.3",
3636
"next": "11.1.4",
3737
"next-plugin-preval": "^1.2.1",
38-
"next-sitemap": "^1.6.203",
3938
"prism-react-renderer": "1.2.1",
4039
"raw-loader": "^4.0.2",
4140
"react": "17",
@@ -62,6 +61,7 @@
6261
"@types/react": "^17.0.2",
6362
"autoprefixer": "^10.2.4",
6463
"eslint-config-next": "12.0.4",
64+
"globby": "^13.1.1",
6565
"json5-loader": "^4.0.1",
6666
"postcss": "^8.2.6",
6767
"tailwindcss": "^2.0.3"
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/**
2+
* Generate SiteMap for SEO Purpose
3+
* We choose to write the script instead of using next-sitemap library because
4+
* next-sitemap library doesn't handle Next.js dynamic path well and it's easier
5+
* to maintain the small script on our own.
6+
* src: https://leerob.io/blog/nextjs-sitemap-robots
7+
*/
8+
9+
import dotenv from 'dotenv-safe';
10+
import { globby } from 'globby';
11+
import prettier from 'prettier';
12+
import { writeFileSync } from 'fs';
13+
14+
dotenv.config();
15+
16+
async function generateSitemap() {
17+
console.log('🗺 ▶️ SiteMap generating...');
18+
const prettierConfig = await prettier.resolveConfig('./.prettierrc.js');
19+
const pagesWithParam = await globby([
20+
'src/pages/**/index.page.tsx',
21+
'src/pages/**/index.page.mdx',
22+
'!data/*.mdx',
23+
'!src/pages/_*.tsx',
24+
'!src/pages/404.page.tsx',
25+
]);
26+
27+
const pages = pagesWithParam.flatMap((p) =>
28+
['react', 'angular', 'vue', 'flutter'].map((framework) =>
29+
p.replace('[platform]', framework)
30+
)
31+
);
32+
33+
const sitemap = `
34+
<?xml version="1.0" encoding="UTF-8"?>
35+
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:mobile="http://www.google.com/schemas/sitemap-mobile/1.0" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
36+
${pages
37+
.map((page) => {
38+
const path = page
39+
.replace('src/pages', '')
40+
.replace('data', '')
41+
.replace('.js', '')
42+
.replace('.page.mdx', '')
43+
.replace('.page.tsx', '')
44+
.replace('/index', '');
45+
const route = path === '/index' ? '' : path;
46+
47+
return `
48+
<url>
49+
<loc>${
50+
process.env.SITE_URL ?? 'https://ui.docs.amplify.aws'
51+
}${route}</loc>
52+
<changefreq>daily</changefreq>
53+
<priority>0.7</priority>
54+
<lastmod>${new Date().toISOString()}</lastmod>
55+
</url>
56+
`;
57+
})
58+
.join('')}
59+
</urlset>
60+
`;
61+
62+
const formatted = prettier.format(sitemap, {
63+
...prettierConfig,
64+
parser: 'html',
65+
});
66+
67+
// eslint-disable-next-line no-sync
68+
writeFileSync('public/sitemap.xml', formatted);
69+
console.log('🗺 ✅ SiteMap generated.');
70+
}
71+
72+
function generateRobotsTxt() {
73+
const isProd = process.env.SITE_URL === 'https://ui.docs.amplify.aws';
74+
console.log(
75+
`🤖▶️ robots.txt generating for ${
76+
isProd
77+
? 'Prod. Googlebot is allowed.'
78+
: 'non-Prod. Googlebot is disallowed.'
79+
}...`
80+
);
81+
const disallowTxt = `# *
82+
User-agent: Googlebot
83+
Disallow: /
84+
`;
85+
86+
const txt = `${
87+
process.env.SITE_URL === 'https://ui.docs.amplify.aws' ? '' : disallowTxt
88+
}
89+
User-agent: *
90+
Allow: /
91+
92+
# Host
93+
Host: https://ui.docs.amplify.aws
94+
95+
# Sitemaps
96+
Sitemap: ${process.env.SITE_URL ?? 'https://ui.docs.amplify.aws'}
97+
`;
98+
writeFileSync('public/robots.txt', txt);
99+
console.log('🤖✅ robots.txt generated.');
100+
}
101+
102+
generateSitemap();
103+
generateRobotsTxt();

docs/src/components/Feature.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
1+
import * as React from 'react';
2+
import * as runtime from 'react/jsx-runtime';
3+
14
import { Alert, VisuallyHidden } from '@aws-amplify/ui-react';
25
import {
36
AstBuilder,
47
GherkinClassicTokenMatcher,
58
Parser,
69
} from '@cucumber/gherkin';
7-
import { IdGenerator } from '@cucumber/messages';
810
import {
911
ClipboardCheckIcon,
1012
CodeIcon,
1113
ExternalLinkIcon,
1214
} from '@heroicons/react/solid';
13-
import { useRouter } from 'next/router';
14-
import * as React from 'react';
15-
import * as runtime from 'react/jsx-runtime';
16-
import remarkGfm from 'remark-gfm';
15+
16+
import { IdGenerator } from '@cucumber/messages';
1717
import { evaluateSync } from '@mdx-js/mdx';
18+
import remarkGfm from 'remark-gfm';
19+
import { useCustomRouter } from '@/components/useCustomRouter';
1820

1921
const parser = new Parser(
2022
new AstBuilder(IdGenerator.uuid()),
@@ -55,7 +57,7 @@ function getGitHubUrlForExample(platform) {
5557

5658
export function Feature({ name = required('Missing feature name') }) {
5759
const [source, setSource] = React.useState(null);
58-
const { pathname, query } = useRouter();
60+
const { pathname, query } = useCustomRouter();
5961
const { platform = 'react' } = query;
6062

6163
const port = getPortForPlatform(platform);

docs/src/components/Fragment.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import dynamic, { LoaderComponent } from 'next/dynamic';
2-
import { useRouter } from 'next/router';
3-
import { isArray } from 'lodash';
41
import * as React from 'react';
52

6-
import { Placeholder, Flex, Link, Alert } from '@aws-amplify/ui-react';
3+
import { Alert, Flex, Link, Placeholder } from '@aws-amplify/ui-react';
4+
import dynamic, { LoaderComponent } from 'next/dynamic';
5+
6+
import { isArray } from 'lodash';
7+
import { useCustomRouter } from '@/components/useCustomRouter';
78

89
export default function Example() {
910
return;
@@ -45,7 +46,7 @@ export const Fragment = ({
4546
platforms,
4647
useCommonWebContent,
4748
}: FragmentProps) => {
48-
const { query } = useRouter();
49+
const { query } = useCustomRouter();
4950
const framework = (query.platform as string) ?? 'react';
5051
const platform = getPlatform(framework, useCommonWebContent);
5152
const Component = React.useMemo(() => {

docs/src/components/Layout/FrameworkChooser.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
1-
import { useRouter } from 'next/router';
21
import {
2+
Image,
33
ToggleButton,
44
ToggleButtonGroup,
5-
Image,
65
VisuallyHidden,
76
} from '@aws-amplify/ui-react';
87

8+
import { useCustomRouter } from '@/components/useCustomRouter';
9+
910
export const FrameworkChooser = ({ platform }) => {
10-
const router = useRouter();
11+
const { replace, pathname } = useCustomRouter();
1112

12-
const chooseFramework = (framework) => {
13+
const chooseFramework = (platform) => {
1314
const { hash } = window.location;
14-
15-
router.replace(
15+
replace(
1616
{
1717
hash,
18-
pathname: router.pathname,
19-
query: { platform: framework },
18+
pathname: pathname === '/' ? '/[platform]' : pathname,
19+
query: { platform },
2020
},
2121
// `as?` prop isn't needed when URL is already provided
2222
undefined,

docs/src/components/Layout/Header.tsx

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,31 @@
11
import * as React from 'react';
2-
import NextLink from 'next/link';
2+
33
import {
44
Button,
5-
VisuallyHidden,
6-
Link,
7-
Flex,
85
ColorMode,
6+
Divider,
7+
Flex,
8+
Link,
99
ToggleButton,
1010
ToggleButtonGroup,
11-
Divider,
1211
View,
12+
VisuallyHidden,
1313
} from '@aws-amplify/ui-react';
1414
import {
15+
MdBedtime,
1516
MdClose,
1617
MdMenu,
17-
MdWbSunny,
18-
MdBedtime,
19-
MdTonality,
2018
MdOpenInNew,
19+
MdTonality,
20+
MdWbSunny,
2121
} from 'react-icons/md';
22-
import { useRouter } from 'next/router';
23-
import { Logo } from '@/components/Logo';
22+
2423
import { FrameworkChooser } from './FrameworkChooser';
25-
import { SecondaryNav } from './SecondaryNav';
2624
import LinkButton from './LinkButton';
25+
import { Logo } from '@/components/Logo';
26+
import NextLink from 'next/link';
27+
import { SecondaryNav } from './SecondaryNav';
28+
import { useCustomRouter } from '@/components/useCustomRouter';
2729

2830
const NavLink = ({
2931
href,
@@ -36,8 +38,10 @@ const NavLink = ({
3638
isExternal?: boolean;
3739
onClick?: React.MouseEventHandler<HTMLAnchorElement>;
3840
}) => {
39-
const { pathname, query } = useRouter();
40-
const isCurrent = pathname.startsWith(href) && href !== '/';
41+
const { pathname } = useCustomRouter();
42+
const pathnameHeader = pathname.split('/')[2];
43+
const hrefHeader = href.split('/')[2];
44+
const isCurrent = pathnameHeader === hrefHeader && href !== `/`;
4145
const className = `docs-nav-link ${isCurrent ? 'current' : ''}`;
4246

4347
if (isExternal) {
@@ -48,7 +52,7 @@ const NavLink = ({
4852
);
4953
}
5054
return (
51-
<NextLink href={{ pathname: href, query }} passHref>
55+
<NextLink href={href} passHref>
5256
<LinkButton href={href} classNames={className} onClick={onClick}>
5357
{children}
5458
</LinkButton>
@@ -65,16 +69,19 @@ const Nav = (props) => (
6569
gap="0"
6670
grow="1"
6771
>
68-
<NavLink {...props} href="/getting-started/installation">
72+
<NavLink
73+
{...props}
74+
href={`/${props.platform}/getting-started/installation`}
75+
>
6976
Getting started
7077
</NavLink>
71-
<NavLink {...props} href="/components">
78+
<NavLink {...props} href={`/${props.platform}/components`}>
7279
Components
7380
</NavLink>
74-
<NavLink {...props} href="/theming">
81+
<NavLink {...props} href={`/${props.platform}/theming`}>
7582
Theming
7683
</NavLink>
77-
<NavLink {...props} href="/guides">
84+
<NavLink {...props} href={`/${props.platform}/guides`}>
7885
Guides
7986
</NavLink>
8087
<Divider orientation="vertical" />
@@ -134,14 +141,14 @@ export const Header = ({ platform, colorMode, setColorMode }) => {
134141
)}
135142
</Button>
136143

137-
<NavLink href="/">
144+
<NavLink href={`/`}>
138145
<span className="docs-logo-link">
139146
<VisuallyHidden>Amplify UI Home</VisuallyHidden>
140147
<Logo />
141148
</span>
142149
</NavLink>
143150

144-
<Nav />
151+
<Nav platform={platform} />
145152

146153
<Settings
147154
colorMode={colorMode}
@@ -162,7 +169,7 @@ export const Header = ({ platform, colorMode, setColorMode }) => {
162169
/>
163170
</Flex>
164171

165-
<Nav onClick={() => setExpanded(false)} />
172+
<Nav onClick={() => setExpanded(false)} platform={platform} />
166173
<nav aria-label="Section navigation" className="docs-sidebar-nav">
167174
<SecondaryNav onClick={() => setExpanded(false)} />
168175
</nav>

0 commit comments

Comments
 (0)