mirror of
https://github.com/hsjobeki/noogle.git
synced 2024-12-23 22:12:55 +03:00
improve SEO
This commit is contained in:
parent
53912303f3
commit
f938e1f95a
@ -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>
|
||||
|
@ -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",
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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 }} />
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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",
|
||||
|
@ -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>
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -46,6 +46,7 @@ export const Header = () => {
|
||||
}}
|
||||
>
|
||||
<Link
|
||||
rel="canonical"
|
||||
href="/"
|
||||
className={fira.className}
|
||||
sx={{
|
||||
|
@ -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"
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user