Skip to content
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

Make it an error to use <a> tags without an exemption. #3991

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
13 changes: 13 additions & 0 deletions Global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,16 @@ declare module '*.jpg' {
export const blurWidth: number;
export const blurHeight: number;
}

type LinkBrand = 'hey. please use project/zemn.me/next/components/Link instead';

declare module 'global' {
global {
namespace JSX {
interface IntrinsicElements {
// Override the `<a>` element
a: { 'data-brand': LinkBrand };
}
}
}
}
12 changes: 11 additions & 1 deletion project/zemn.me/next/components/Link/Link.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ function isFirstPartyURL(u: string | UrlObject | URL): boolean {
);
}

type Exempt<T> = T & { 'data-brand': LinkBrand };

export function Link({ href, rel, target, ...props }: LinkProps) {
if (href !== undefined && !isFirstPartyURL(href)) {
rel = `${rel ?? ''} external`.trim();
Expand All @@ -62,7 +64,15 @@ export function Link({ href, rel, target, ...props }: LinkProps) {
// next Link has a strangely strident stance on providing the href parameter
// which we do not. if there is no href we just fall back to using an <a> tag.
// https://github.com/i18next/next-i18next/issues/599
if (href === undefined) return <a {...{ href, rel, target, ...props }} />;
if (href === undefined) {
const p = {
href,
rel,
target,
...props,
};
return <a {...(props as Exempt<typeof p>)} />;
}
return <NextLink {...{ href, rel, target, ...props }} />;
}

Expand Down
16 changes: 8 additions & 8 deletions project/zemn.me/next/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -145,19 +145,19 @@ export default function Main() {
<p>
The background video (“hero video”) is of a hidden
area in the gardens of{' '}
<a href="https://en.wikipedia.org/wiki/Kenwood_House">
<Link href="https://en.wikipedia.org/wiki/Kenwood_House">
Kenwood House
</a>
</Link>
, a beautiful stately home sandwiched between
Highgate and Hampstead in London where I grew up.
It's located at about{' '}
<a
<Link
href="https://goo.gl/maps/JEAzn2kZgu6pyaNA6"
rel="nofollow"
title="Location of the Kenwood video"
>
51.57139601074658°N, -0.16924392259112794°E
</a>
</Link>
.
</p>
<p>
Expand All @@ -171,9 +171,9 @@ export default function Main() {
<p>
The type and style itself was inspired by older,
pre-computer era typsetting such as the{' '}
<a href="https://assets.lloyds.com/assets/pdf-lloyds-acts-mar07lloydsact1871/1/pdf-lloyds-acts-Mar07LloydsAct1871.pdf">
<Link href="https://assets.lloyds.com/assets/pdf-lloyds-acts-mar07lloydsact1871/1/pdf-lloyds-acts-Mar07LloydsAct1871.pdf">
Lloyd's Act 1871
</a>
</Link>
. Particular effort was put into trying to have
content fill horizontal space automatically, as seen
in older documents that try to make the most of the
Expand Down Expand Up @@ -211,9 +211,9 @@ export default function Main() {
</p>
<p>
The eye logo is a reference to the well-known{' '}
<a href="https://en.wikipedia.org/wiki/Eye_of_Providence">
<Link href="https://en.wikipedia.org/wiki/Eye_of_Providence">
‘eye of providence’
</a>
</Link>
, a symbol that represents human achievement as
being incomplete without God. I wanted it to reflect
the idea that, in a universe that might not have a
Expand Down
Loading