improve SEO

This commit is contained in:
Johannes Kirschbauer 2024-01-22 14:36:57 +01:00
parent 53912303f3
commit f938e1f95a
No known key found for this signature in database
12 changed files with 84 additions and 22 deletions

View File

@ -3,7 +3,7 @@ import { ShareButton } from "@/components/ShareButton";
import { BackButton } from "@/components/BackButton";
import { Doc, data, manualLinks } from "@/models/data";
import { getPrimopDescription } from "@/models/primop";
import { extractHeadings, mdxRenderOptions } from "@/utils";
import { extractExcerpt, extractHeadings, mdxRenderOptions } from "@/utils";
import { Box, Divider, Typography, Link, Chip } from "@mui/material";
import { MDXRemote } from "next-mdx-remote/rsc";
import { findType, interpretType } from "@/models/nix";
@ -50,10 +50,12 @@ const Toc = async (props: TocProps) => {
whiteSpace: "nowrap",
}}
>
<Typography variant="subtitle1">On this page</Typography>
<Typography variant="subtitle1" component={"div"}>
On this page
</Typography>
<Box sx={{ display: "flex", flexDirection: "column" }}>
{title && (
<Link href={`#${title}`}>
<Link rel="canonical" href={`#${title}`}>
<Typography
variant="body2"
sx={{
@ -68,7 +70,7 @@ const Toc = async (props: TocProps) => {
</Link>
)}
{headings.map((h, idx) => (
<Link key={idx} href={`#${h.id}`}>
<Link rel="canonical" key={idx} href={`#${h.id}`}>
<Typography
variant="body2"
sx={{
@ -171,10 +173,25 @@ export async function generateMetadata(
const keywords = item?.meta?.path || [];
const alias_keywords = item?.meta.aliases?.flat() || [];
const title = item?.meta.path[item?.meta.path.length - 1];
// words?.forEach((word) => {
// console.log({ word });
// });
// console.log({ excerpt });
const name = item?.meta.path[item?.meta.path.length - 1];
const content = item?.content?.content || "";
const summary = await extractExcerpt(content, 35);
const description = await extractExcerpt(content, 200);
const title = `Nix ${name} - ${summary}`;
return {
// should be 20-70 characters
title,
description: item?.content?.content,
// should be 70-160 characters
description,
authors: [
{ name: "nixos", url: "https://nixos.org/" },
{ name: "nixpkgs", url: "https://github.com/NixOS/nixpkgs" },
@ -233,7 +250,7 @@ export default async function Page(props: { params: { path: string[] } }) {
idx === all.length - 1 ? (
<React.Fragment key={idx}>
<meta data-pagefind-meta={`name:${attr}`} />
<Box component="h3" sx={{ display: "none" }}>
<Box component="h2" sx={{ display: "none" }}>
{attr}
</Box>
</React.Fragment>
@ -348,7 +365,7 @@ export default async function Page(props: { params: { path: string[] } }) {
<Divider flexItem />
<Typography
variant="subtitle1"
component={"h3"}
component={"h4"}
sx={{
color: "text.secondary",
alignSelf: "center",
@ -366,14 +383,16 @@ export default async function Page(props: { params: { path: string[] } }) {
This is a Functor
</Typography>
<br />
<Link href="/md/tutorials/functors">Learn about functors</Link>
<Link rel="canonical" href="/md/tutorials/functors">
Learn about functors
</Link>
</>
)}
{!!meta?.aliases?.length && (
<>
<Typography
variant="h5"
component={"div"}
component={"h5"}
sx={{ color: "text.secondary" }}
>
Aliases
@ -381,7 +400,9 @@ export default async function Page(props: { params: { path: string[] } }) {
<ul>
{meta?.aliases?.map((a) => (
<li key={a.join(".")}>
<Link href={`/f/${a.join("/")}`}>{a.join(".")}</Link>
<Link rel="canonical" href={`/f/${a.join("/")}`}>
{a.join(".")}
</Link>
</li>
))}
</ul>

View File

@ -6,7 +6,7 @@ import { ClientSideLayoutContext } from "@/components/ClientSideLayoutContext";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "Noogle",
title: "Noogle - Simply find Nix API reference documentation.",
description:
"Nix API reference. Includes nix, nixpkgs and nixos. Search nix functions within the nix ecosystem based on type, name, description, example, category and more.",
creator: "@hsjobeki",

View File

@ -24,7 +24,7 @@ export default function Home() {
alignItems: "center",
}}
>
<Link href="/md/release/2024-1" underline="none">
<Link rel="canonical" href="/md/release/2024-1" underline="none">
<Tooltip title="Whats new">
<Typography
variant="h1"

View File

@ -19,7 +19,7 @@ export const ListGroup = async (props: ListGroupProps) => {
const matter = await getMdxMeta(entry);
const { frontmatter } = matter.compiled;
return (
<Link key={`${idx}`} href={`/ref/${entry.join("/")}`}>
<Link rel="canonical" key={`${idx}`} href={`/ref/${entry.join("/")}`}>
<ListItem
disablePadding
disableGutters

View File

@ -284,7 +284,11 @@ export function PagefindResults() {
secondaryTypographyProps={{
variant: "body1",
}}
primary={<Link href={`${url}`}>{meta.title}</Link>}
primary={
<Link rel="canonical" href={`${url}`}>
{meta.title}
</Link>
}
secondary={
<div dangerouslySetInnerHTML={{ __html: excerpt }} />
}

View File

@ -49,6 +49,7 @@ export const PositionLink = ({
<>
<Typography
variant="subtitle1"
component={"div"}
sx={{ color: "text.secondary", pb: 2 }}
>
This function is not declared in a .nix file
@ -56,6 +57,7 @@ export const PositionLink = ({
{!is_primop && (
<Typography
variant="subtitle2"
component={"div"}
sx={{ color: "text.secondary", pb: 2 }}
>
This is very likely a bug in noogle please report this error.
@ -143,7 +145,11 @@ export const PositionLink = ({
</Box>
)}
</Typography>
<Typography variant="subtitle2" sx={{ color: "text.secondary" }}>
<Typography
variant="subtitle2"
component={"div"}
sx={{ color: "text.secondary" }}
>
{contentPosition &&
is_inherited &&
`(${content_meta?.path?.join(".")})`}
@ -151,7 +157,7 @@ export const PositionLink = ({
</Box>
{!content?.content && (
<>
<Typography variant="h5" sx={{ pt: 2 }}>
<Typography variant="h5" component={"div"} sx={{ pt: 2 }}>
{"Contribute"}
</Typography>
<Typography
@ -184,7 +190,6 @@ export const PositionLink = ({
secondary="Contribute to Noogle"
/>
</ListItemButton>
{/* </Link> */}
</ListItem>
)}
</List>

View File

@ -90,6 +90,7 @@ export const Navigation = ({
<Box sx={{ display: "flex", alignItems: "center" }}>
{prev && (
<Link
rel="canonical"
href={prev.url}
sx={{
my: 2,
@ -111,6 +112,7 @@ export const Navigation = ({
{next && (
<Link
rel="canonical"
href={next.url}
sx={{
ml: "auto",

View File

@ -116,7 +116,10 @@ export function SearchResults() {
variant: "body1",
}}
primary={
<Link href={`f/${meta.path.join("/")}`}>
<Link
rel="canonical"
href={`f/${meta.path.join("/")}`}
>
{meta.title}
</Link>
}

View File

@ -133,7 +133,11 @@ export const Filter = (props: FilterProps) => {
}}
>
<Box sx={{ display: "flex", alignItems: "center", pr: 1 }}>
<Typography variant="subtitle2" sx={{ color: "text.secondary" }}>
<Typography
variant="subtitle2"
component="div"
sx={{ color: "text.secondary" }}
>
From
</Typography>
</Box>
@ -184,7 +188,11 @@ export const Filter = (props: FilterProps) => {
}}
>
<Box sx={{ display: "flex", alignItems: "center", pr: 1 }}>
<Typography variant="subtitle2" sx={{ color: "text.secondary" }}>
<Typography
variant="subtitle2"
component="div"
sx={{ color: "text.secondary" }}
>
To
</Typography>
</Box>

View File

@ -46,6 +46,7 @@ export const Header = () => {
}}
>
<Link
rel="canonical"
href="/"
className={fira.className}
sx={{

View File

@ -34,7 +34,7 @@ export const Preview = (props: PreviewProps) => {
width: "100%",
}}
>
<Link href={`/f/${meta.path.join("/")}`}>
<Link rel="canonical" href={`/f/${meta.path.join("/")}`}>
<Typography
component="h3"
variant="h4"

View File

@ -17,6 +17,7 @@ import remarkRehype from "remark-rehype";
import remarkUnlink from "remark-unlink";
import { unified } from "unified";
import { rehypeExtractExcerpt } from "./excerpt";
/**
* Function to generate a set from a path in lodash style
@ -112,6 +113,23 @@ type Heading = {
id: string;
};
export const extractExcerpt = async (
content: string,
maxLength: number
): Promise<string> => {
const processor = unified()
.use(remarkParse)
.use(remarkRehype)
.use(rehypeExtractExcerpt, {
maxLength: maxLength,
ellipsis: " ...",
})
.use(rehypeStringify);
const result = await processor.process(content);
return result.data.excerpt as string;
};
export const extractHeadings = async (content: string): Promise<Heading[]> => {
const processor = unified()
.use(remarkParse)