feat: move to marmite
This commit is contained in:
parent
d7952ad640
commit
4e3576d4a7
@ -1,3 +1,4 @@
|
|||||||
node_modules
|
.gitignore
|
||||||
build
|
site
|
||||||
public/build
|
LICENSE
|
||||||
|
README.md
|
18
.github/workflow/code_quality.yaml
vendored
18
.github/workflow/code_quality.yaml
vendored
@ -1,18 +0,0 @@
|
|||||||
name: Code quality
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
code_quality:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Setup Biome
|
|
||||||
uses: biomejs/setup-biome@v2
|
|
||||||
with:
|
|
||||||
version: latest
|
|
||||||
- name: Run Biome
|
|
||||||
run: biome ci .
|
|
8
.gitignore
vendored
8
.gitignore
vendored
@ -1,6 +1,2 @@
|
|||||||
node_modules
|
.env
|
||||||
|
site
|
||||||
/.cache
|
|
||||||
/build
|
|
||||||
/public/build
|
|
||||||
.env
|
|
18
Dockerfile
18
Dockerfile
@ -1,19 +1,9 @@
|
|||||||
FROM node:22-alpine AS base
|
FROM ghcr.io/rochacbruno/marmite
|
||||||
|
|
||||||
RUN apk add --no-cache libc6-compat
|
WORKDIR /input
|
||||||
|
|
||||||
WORKDIR /app
|
COPY . ./
|
||||||
|
|
||||||
COPY package.json package-lock.json ./
|
|
||||||
|
|
||||||
RUN npm ci
|
|
||||||
|
|
||||||
COPY . .
|
|
||||||
|
|
||||||
RUN npm run build && npm cache clean --force
|
|
||||||
|
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
|
|
||||||
ENV PORT 3000
|
CMD ["--serve", "--bind", "0.0.0.0:3000"]
|
||||||
|
|
||||||
CMD ["npm", "run", "start"]
|
|
@ -1,3 +1,3 @@
|
|||||||
# yaaaw.it
|
# nullndr.com
|
||||||
|
|
||||||
This is my personal website made with [remix.run](remix.run/docs) 🚀
|
This is my personal website made with [marmite](https://rochacbruno.github.io/marmite/) 🚀
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
export function Body({ children }: React.PropsWithChildren) {
|
|
||||||
return (
|
|
||||||
<body className="bg-[#222447] text-[#d6d6d6] font-['monospace']">
|
|
||||||
{children}
|
|
||||||
</body>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
export function LinkWrapper({ children }: React.PropsWithChildren) {
|
|
||||||
return <div className="mt-5 hover:text-[#e6c2bf] font-bold">{children}</div>;
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
export function Notbyai() {
|
|
||||||
return (
|
|
||||||
<div className="flex flex-col items-center">
|
|
||||||
<a href="https://notbyai.fyi/" target="_blank" rel="noreferrer">
|
|
||||||
<img
|
|
||||||
alt="nobyai logo"
|
|
||||||
src="https://user-images.githubusercontent.com/62137266/225653923-a69103f5-b318-4e52-9ea1-95b61d388366.svg"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
import type { SerializeFrom } from "@remix-run/node";
|
|
||||||
import { Link } from "@remix-run/react";
|
|
||||||
import { useFormattedDate } from "~/hooks";
|
|
||||||
import type { Post } from "~/utils/posts.server";
|
|
||||||
|
|
||||||
export function PostPreview({
|
|
||||||
title,
|
|
||||||
description,
|
|
||||||
filename,
|
|
||||||
published,
|
|
||||||
}: SerializeFrom<Post>) {
|
|
||||||
const formattedDate = useFormattedDate(published);
|
|
||||||
return (
|
|
||||||
<div className="">
|
|
||||||
<Link to={filename}>
|
|
||||||
<div className="py-3 font-bold">
|
|
||||||
<div className="text-[#ffff00]">{title}</div>
|
|
||||||
<div>{description}</div>
|
|
||||||
<time className="text-sm">{formattedDate}</time>
|
|
||||||
</div>
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
export function Title({ children }: React.PropsWithChildren) {
|
|
||||||
return (
|
|
||||||
<div className="mt-5">
|
|
||||||
<h1 className="text-[#ffff00] text-2xl font-bold">{children}</h1>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
export * from "./useFormattedDate";
|
|
@ -1,6 +0,0 @@
|
|||||||
export function useFormattedDate(_date: Date) {
|
|
||||||
const date = new Date(_date);
|
|
||||||
const month = date.getUTCMonth().toString().padStart(2, "0");
|
|
||||||
const monthDate = date.getUTCDate().toString().padStart(2, "0");
|
|
||||||
return `${date.getUTCFullYear()}-${month}-${monthDate}`;
|
|
||||||
}
|
|
101
app/root.tsx
101
app/root.tsx
@ -1,101 +0,0 @@
|
|||||||
import codeHikeStyle from "@code-hike/mdx/dist/index.css?url";
|
|
||||||
import type { LinksFunction, MetaFunction } from "@remix-run/node";
|
|
||||||
import {
|
|
||||||
Link,
|
|
||||||
Links,
|
|
||||||
Meta,
|
|
||||||
Outlet,
|
|
||||||
Scripts,
|
|
||||||
ScrollRestoration,
|
|
||||||
isRouteErrorResponse,
|
|
||||||
useRouteError,
|
|
||||||
} from "@remix-run/react";
|
|
||||||
import stylesheet from "~/tailwind.css?url";
|
|
||||||
import { Body } from "./components/Body";
|
|
||||||
import { LinkWrapper } from "./components/LinkWrapper";
|
|
||||||
|
|
||||||
export const links: LinksFunction = () => [
|
|
||||||
{ rel: "stylesheet", href: stylesheet },
|
|
||||||
{ rel: "stylesheet", href: codeHikeStyle },
|
|
||||||
];
|
|
||||||
|
|
||||||
export const meta: MetaFunction = () => [
|
|
||||||
{
|
|
||||||
charSet: "utf-8",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Nullndr",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "viewport",
|
|
||||||
content: "width=device-width,initial-scale=1.0",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export function Layout({ children }: React.PropsWithChildren) {
|
|
||||||
return (
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<Meta />
|
|
||||||
<Links />
|
|
||||||
<script
|
|
||||||
defer
|
|
||||||
data-domain="nullndr.com"
|
|
||||||
src="https://plausible.nullndr.com/js/script.file-downloads.hash.outbound-links.pageview-props.tagged-events.js"
|
|
||||||
/>
|
|
||||||
<script
|
|
||||||
dangerouslySetInnerHTML={{
|
|
||||||
__html:
|
|
||||||
"window.plausible = window.plausible || function(){(window.plausible.q = window.plausible.q || []).push(arguments)}",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</head>
|
|
||||||
<Body>
|
|
||||||
{children}
|
|
||||||
<ScrollRestoration />
|
|
||||||
<Scripts />
|
|
||||||
</Body>
|
|
||||||
</html>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function App() {
|
|
||||||
return <Outlet />;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function ErrorBoundary() {
|
|
||||||
const error = useRouteError();
|
|
||||||
|
|
||||||
if (isRouteErrorResponse(error)) {
|
|
||||||
return (
|
|
||||||
<div className="flex flex-col items-center justify-around h-[100vh]">
|
|
||||||
<div>
|
|
||||||
<div className="text-center text-[#ffff00] text-[10vw] font-bold">
|
|
||||||
404
|
|
||||||
</div>
|
|
||||||
<div className="font-bold">Where do you think you are going?</div>
|
|
||||||
<div className="text-center">
|
|
||||||
<LinkWrapper>
|
|
||||||
<Link to="/">Home</Link>
|
|
||||||
</LinkWrapper>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="flex flex-col items-center justify-around h-[100vh]">
|
|
||||||
<div>
|
|
||||||
<div className="text-center text-[#ffff00] text-[6vw] font-bold">
|
|
||||||
Something bad happened
|
|
||||||
</div>
|
|
||||||
<div className="text-center">
|
|
||||||
<LinkWrapper>
|
|
||||||
<Link to="/">Home</Link>
|
|
||||||
</LinkWrapper>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,65 +0,0 @@
|
|||||||
import { Link } from "@remix-run/react";
|
|
||||||
import {
|
|
||||||
FaGithub,
|
|
||||||
FaGitlab,
|
|
||||||
FaLinkedin,
|
|
||||||
FaMastodon,
|
|
||||||
FaStackOverflow,
|
|
||||||
FaTelegramPlane,
|
|
||||||
FaTwitter,
|
|
||||||
} from "react-icons/fa";
|
|
||||||
import { IconContext } from "react-icons/lib";
|
|
||||||
import { MdEmail } from "react-icons/md";
|
|
||||||
import { LinkWrapper } from "~/components/LinkWrapper";
|
|
||||||
import { Notbyai } from "~/components/Notbyai";
|
|
||||||
|
|
||||||
export default function Index() {
|
|
||||||
return (
|
|
||||||
<div className="flex h-screen min-h-full flex-col justify-center">
|
|
||||||
<div className="flex flex-col flex-grow place-content-center">
|
|
||||||
<div>
|
|
||||||
<div className="text-center text-[6vw]">
|
|
||||||
<span>$ echo "Hello, world!"</span>
|
|
||||||
<span className="animate-blink">|</span>
|
|
||||||
</div>
|
|
||||||
<nav className="pt-5 flex justify-center flex-wrap">
|
|
||||||
<Notbyai />
|
|
||||||
<IconContext.Provider
|
|
||||||
value={{ color: "yellow", className: "p-2", size: "3em" }}
|
|
||||||
>
|
|
||||||
<a rel="me" href="https://mastodon.uno/@nullndr">
|
|
||||||
<FaMastodon />
|
|
||||||
</a>
|
|
||||||
<a href="https://t.me/nullndr">
|
|
||||||
<FaTelegramPlane />
|
|
||||||
</a>
|
|
||||||
<a href="https://gitlab.com/nullndr">
|
|
||||||
<FaGitlab />
|
|
||||||
</a>
|
|
||||||
<a href="https://github.com/nullndr">
|
|
||||||
<FaGithub />
|
|
||||||
</a>
|
|
||||||
<a href="https://twitter.com/nullndr">
|
|
||||||
<FaTwitter />
|
|
||||||
</a>
|
|
||||||
<a href="mailto: nullndr@duck.com">
|
|
||||||
<MdEmail />
|
|
||||||
</a>
|
|
||||||
<a href="https://linkedin.com/in/nullndr">
|
|
||||||
<FaLinkedin />
|
|
||||||
</a>
|
|
||||||
<a href="https://stackoverflow.com/users/10503039/nullndr">
|
|
||||||
<FaStackOverflow />
|
|
||||||
</a>
|
|
||||||
</IconContext.Provider>
|
|
||||||
</nav>
|
|
||||||
<div className="flex justify-center items-center space-x-6">
|
|
||||||
<LinkWrapper>
|
|
||||||
<Link to="/blog">Blog</Link>
|
|
||||||
</LinkWrapper>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,97 +0,0 @@
|
|||||||
import type { LoaderFunctionArgs, MetaFunction } from "@remix-run/node";
|
|
||||||
import { Link, useLoaderData } from "@remix-run/react";
|
|
||||||
import { getMDXComponent } from "mdx-bundler/client/index.js";
|
|
||||||
import React from "react";
|
|
||||||
import { FaEdit } from "react-icons/fa";
|
|
||||||
import { Notbyai } from "~/components/Notbyai";
|
|
||||||
import { Title } from "~/components/Title";
|
|
||||||
import { useFormattedDate } from "~/hooks";
|
|
||||||
import { getMdxFile } from "~/utils/posts.server";
|
|
||||||
|
|
||||||
export const handle = {
|
|
||||||
to: "/blog",
|
|
||||||
text: "Go Back",
|
|
||||||
};
|
|
||||||
|
|
||||||
export const loader = async ({ params }: LoaderFunctionArgs) => {
|
|
||||||
const file = params.file;
|
|
||||||
if (file == null) {
|
|
||||||
throw new Response(null, { status: 400 });
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = await getMdxFile(file);
|
|
||||||
return { ...data, file };
|
|
||||||
};
|
|
||||||
|
|
||||||
export const meta: MetaFunction<typeof loader> = ({ data }) => {
|
|
||||||
if (data == null) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
const {
|
|
||||||
frontmatter: { title, description },
|
|
||||||
} = data;
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
title,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
property: "og:title",
|
|
||||||
content: title,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
property: "description",
|
|
||||||
content: description,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function Post() {
|
|
||||||
const {
|
|
||||||
code,
|
|
||||||
frontmatter: { title, date },
|
|
||||||
file,
|
|
||||||
} = useLoaderData<typeof loader>();
|
|
||||||
const formattedDate = useFormattedDate(date);
|
|
||||||
const MdxComponent = React.useMemo(() => getMDXComponent(code), [code]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="mx-2">
|
|
||||||
<header>
|
|
||||||
<Title>{title}</Title>
|
|
||||||
<span>
|
|
||||||
<time>{formattedDate}</time> ·{" "}
|
|
||||||
<Link to="/blog" className="hover:text-[#e6c2bf] font-bold">
|
|
||||||
Go Back
|
|
||||||
</Link>
|
|
||||||
</span>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<main>
|
|
||||||
<div className="space-y-5">
|
|
||||||
<div className=" prose-blockquote:bg-[#282c34] prose-blockquote:border-l-4 prose-blockquote:border-[#21252b] prose-blockquote:px-2 prose-blockquote:py-2 prose-blockquote:rounded-r">
|
|
||||||
<div className="prose-h2:text-[#ffff00] prose-h2:font-bold prose-h2:text-2xl">
|
|
||||||
<div className="prose-code:px-1 prose-code:py-0.5 prose-code:bg-[#282c34] prose-code:text-[#d6d6d6] prose-code:rounded prose-code:font-mono">
|
|
||||||
<div className="space-y-5 dark:prose-invert prose-a:font-bold hover:prose-a:text-[#ffff00] prose-p:text-[#d6d6d6]">
|
|
||||||
<MdxComponent />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Notbyai />
|
|
||||||
<div>
|
|
||||||
<Link
|
|
||||||
to={`https://github.com/nullndr/website/edit/main/posts/${file}.mdx`}
|
|
||||||
className="hover:text-[#ffff00]"
|
|
||||||
>
|
|
||||||
<div className="flex justify-end items-center space-x-2 pb-5">
|
|
||||||
<FaEdit />
|
|
||||||
<div className="font-bold">Typo?</div>
|
|
||||||
</div>
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
import { Link, useLoaderData } from "@remix-run/react";
|
|
||||||
import { LinkWrapper } from "~/components/LinkWrapper";
|
|
||||||
import { PostPreview } from "~/components/PostPreview";
|
|
||||||
import { Title } from "~/components/Title";
|
|
||||||
import { findPosts } from "~/utils/posts.server";
|
|
||||||
|
|
||||||
export const loader = () => {
|
|
||||||
return findPosts();
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function Blog() {
|
|
||||||
const posts = useLoaderData<typeof loader>();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="mx-2">
|
|
||||||
<LinkWrapper>
|
|
||||||
<Link to="/">Home</Link>
|
|
||||||
</LinkWrapper>
|
|
||||||
<Title>Here I blog about whatever get my attention</Title>
|
|
||||||
<div className="mt-5">
|
|
||||||
{posts.map((post) => (
|
|
||||||
<PostPreview {...post} key={post.title} />
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
import type { MetaFunction } from "@remix-run/node";
|
|
||||||
import { Outlet } from "react-router-dom";
|
|
||||||
|
|
||||||
export const meta: MetaFunction = () => {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
title: "Nullndr's blog",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
property: "og:title",
|
|
||||||
content: "Nullndr's blog",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
property: "description",
|
|
||||||
content: "Another blog by Nullndr.",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function BlogLayout() {
|
|
||||||
return (
|
|
||||||
<div className="space-y-6 max-w-3xl mx-auto">
|
|
||||||
<Outlet />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
@tailwind base;
|
|
||||||
@tailwind components;
|
|
||||||
@tailwind utilities;
|
|
@ -1,81 +0,0 @@
|
|||||||
import { remarkCodeHike } from "@code-hike/mdx";
|
|
||||||
import { bundleMDX } from "mdx-bundler";
|
|
||||||
import { readFile, readdir } from "node:fs/promises";
|
|
||||||
import path from "node:path";
|
|
||||||
|
|
||||||
type FrontMatter = {
|
|
||||||
title: string;
|
|
||||||
description: string;
|
|
||||||
date: Date;
|
|
||||||
isFeatured: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getMdxFile = async (file: string) => {
|
|
||||||
const filePath = path.join(process.cwd(), `posts/${file}.mdx`);
|
|
||||||
const postContent = (await readFile(filePath)).toString();
|
|
||||||
return bundleMDX<FrontMatter>({
|
|
||||||
source: postContent,
|
|
||||||
mdxOptions(options) {
|
|
||||||
return {
|
|
||||||
rehypePlugins: [...(options.rehypePlugins ?? [])],
|
|
||||||
remarkPlugins: [
|
|
||||||
...(options.remarkPlugins ?? []),
|
|
||||||
[
|
|
||||||
remarkCodeHike,
|
|
||||||
{
|
|
||||||
theme: "one-dark-pro",
|
|
||||||
lineNumbers: true,
|
|
||||||
showCopyButton: true,
|
|
||||||
autoImport: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
],
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Post = Omit<FrontMatter, "published"> & {
|
|
||||||
filename: string;
|
|
||||||
published: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const findPosts = async () => {
|
|
||||||
const files = await readdir("posts");
|
|
||||||
const posts = await Promise.all(
|
|
||||||
files
|
|
||||||
.filter((file) => file.endsWith(".mdx"))
|
|
||||||
.map(async (file) => {
|
|
||||||
const filePath = path.join(process.cwd(), `posts/${file}`);
|
|
||||||
const postContent = (await readFile(filePath)).toString();
|
|
||||||
const { frontmatter } = await bundleMDX<FrontMatter>({
|
|
||||||
source: postContent,
|
|
||||||
mdxOptions() {
|
|
||||||
return {
|
|
||||||
remarkPlugins: [
|
|
||||||
[
|
|
||||||
remarkCodeHike,
|
|
||||||
{
|
|
||||||
theme: "one-dark-pro",
|
|
||||||
lineNumbers: true,
|
|
||||||
showCopyButton: true,
|
|
||||||
autoImport: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
],
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
...frontmatter,
|
|
||||||
filename: file.replace(".mdx", ""),
|
|
||||||
published: frontmatter.date.toISOString(),
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
return posts.sort((a, b) =>
|
|
||||||
new Date(a.published) > new Date(b.published) ? -1 : 1,
|
|
||||||
);
|
|
||||||
};
|
|
54
biome.json
54
biome.json
@ -1,54 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://biomejs.dev/schemas/1.9.3/schema.json",
|
|
||||||
"files": {
|
|
||||||
"ignoreUnknown": false,
|
|
||||||
"ignore": ["node_modules", "build"]
|
|
||||||
},
|
|
||||||
"vcs": {
|
|
||||||
"clientKind": "git",
|
|
||||||
"defaultBranch": "main",
|
|
||||||
"enabled": false,
|
|
||||||
"root": ".",
|
|
||||||
"useIgnoreFile": true
|
|
||||||
},
|
|
||||||
"linter": {
|
|
||||||
"enabled": true,
|
|
||||||
"rules": {
|
|
||||||
"recommended": true,
|
|
||||||
"suspicious": {
|
|
||||||
"noExplicitAny": "off",
|
|
||||||
"noConfusingVoidType": "off"
|
|
||||||
},
|
|
||||||
"security": {
|
|
||||||
"noDangerouslySetInnerHtml": "off"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"formatter": {
|
|
||||||
"enabled": true,
|
|
||||||
"indentStyle": "space",
|
|
||||||
"indentWidth": 2,
|
|
||||||
"lineEnding": "lf"
|
|
||||||
},
|
|
||||||
"organizeImports": {
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
"javascript": {
|
|
||||||
"formatter": {
|
|
||||||
"enabled": true,
|
|
||||||
"quoteStyle": "double",
|
|
||||||
"jsxQuoteStyle": "double",
|
|
||||||
"trailingCommas": "all",
|
|
||||||
"semicolons": "always",
|
|
||||||
"arrowParentheses": "always"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"overrides": [
|
|
||||||
{
|
|
||||||
"include": ["**/*.{ts,tsx}"],
|
|
||||||
"javascript": {
|
|
||||||
"globals": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
8
content/_htmlhead.md
Normal file
8
content/_htmlhead.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<script
|
||||||
|
defer
|
||||||
|
data-domain="nullndr.com"
|
||||||
|
src="https://plausible.nullndr.com/js/script.file-downloads.hash.outbound-links.pageview-props.tagged-events.js"
|
||||||
|
></script>
|
||||||
|
<script>
|
||||||
|
window.plausible = window.plausible || function(){(window.plausible.q = window.plausible.q || []).push(arguments)},
|
||||||
|
</script>
|
@ -2,8 +2,11 @@
|
|||||||
title: Hello, world
|
title: Hello, world
|
||||||
date: 2023-03-15
|
date: 2023-03-15
|
||||||
description: The hello world post
|
description: The hello world post
|
||||||
|
author: nullndr
|
||||||
---
|
---
|
||||||
|
|
||||||
|
# Hello, world
|
||||||
|
|
||||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
||||||
Libero id faucibus nisl tincidunt eget nullam non. Viverra suspendisse potenti nullam ac.
|
Libero id faucibus nisl tincidunt eget nullam non. Viverra suspendisse potenti nullam ac.
|
||||||
Neque volutpat ac tincidunt vitae semper quis. Libero justo laoreet sit amet cursus sit amet dictum.
|
Neque volutpat ac tincidunt vitae semper quis. Libero justo laoreet sit amet cursus sit amet dictum.
|
@ -2,8 +2,11 @@
|
|||||||
title: How this site is built
|
title: How this site is built
|
||||||
date: 2024-09-29
|
date: 2024-09-29
|
||||||
description: A technical explanation of how this site works
|
description: A technical explanation of how this site works
|
||||||
|
author: nullndr
|
||||||
---
|
---
|
||||||
|
|
||||||
|
# How this site is built
|
||||||
|
|
||||||
This site is built with [remix.run](https://remix.run). There is no database for the posts, instead the posts are written directly in [MDX](https://mdxjs.com/).
|
This site is built with [remix.run](https://remix.run). There is no database for the posts, instead the posts are written directly in [MDX](https://mdxjs.com/).
|
||||||
|
|
||||||
The transformation from MDX to the component is done with the following function:
|
The transformation from MDX to the component is done with the following function:
|
@ -2,8 +2,12 @@
|
|||||||
title: Run Shopify App without the App Bridge
|
title: Run Shopify App without the App Bridge
|
||||||
date: 2024-10-07
|
date: 2024-10-07
|
||||||
description: Let's get rid of Shopify's app bridge.
|
description: Let's get rid of Shopify's app bridge.
|
||||||
|
tags: shopify
|
||||||
|
author: nullndr
|
||||||
---
|
---
|
||||||
|
|
||||||
|
# Run Shopify App without the App Bridge
|
||||||
|
|
||||||
This post wants to explain how to run a Shopify'app outside the [cli](https://github.com/Shopify/cli) and the [app bridge](https://shopify.dev/docs/api/app-bridge).
|
This post wants to explain how to run a Shopify'app outside the [cli](https://github.com/Shopify/cli) and the [app bridge](https://shopify.dev/docs/api/app-bridge).
|
||||||
|
|
||||||
> Please pay attention, you won't be able to use anything from the App Bridge API. The installation process is also affected, since you won't be able to
|
> Please pay attention, you won't be able to use anything from the App Bridge API. The installation process is also affected, since you won't be able to
|
2
env.d.ts
vendored
2
env.d.ts
vendored
@ -1,2 +0,0 @@
|
|||||||
/// <reference types="vite/client" />
|
|
||||||
/// <reference types="@remix-run/node" />
|
|
19
marmite.yaml
Normal file
19
marmite.yaml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
name: "Nullndr's blog"
|
||||||
|
tagline: "Another blog by Nullndr"
|
||||||
|
url: "https://nullndr.com"
|
||||||
|
pagination: 10
|
||||||
|
enable_search: true
|
||||||
|
menu:
|
||||||
|
- ["Tags", "tags.html"]
|
||||||
|
- ["Archive", "archive.html"]
|
||||||
|
- ["GitHub", "https://github.com/nullndr"]
|
||||||
|
authors:
|
||||||
|
nullndr:
|
||||||
|
name: "Andrea Foletto"
|
||||||
|
avatar: "https://avatars.githubusercontent.com/u/62137266?v=4"
|
||||||
|
links:
|
||||||
|
- ["Telegram", "https://t.me/nullndr"]
|
||||||
|
- ["Linkedin", "https://linkedin.com/in/nullndr"]
|
||||||
|
- ["X", "https://x.com/nullndr"]
|
||||||
|
- ["StackOverflow", "https://stackoverflow.com/users/10503039/nullndr"]
|
||||||
|
- ["GitHub", "https://github.com/nullndr"]
|
12263
package-lock.json
generated
12263
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
43
package.json
43
package.json
@ -1,43 +0,0 @@
|
|||||||
{
|
|
||||||
"private": true,
|
|
||||||
"sideEffects": false,
|
|
||||||
"type": "module",
|
|
||||||
"scripts": {
|
|
||||||
"build": "remix vite:build",
|
|
||||||
"dev": "remix vite:dev",
|
|
||||||
"start": "remix-serve ./build/server/index.js",
|
|
||||||
"typecheck": "tsc",
|
|
||||||
"lint": "biome lint",
|
|
||||||
"format": "biome format --write",
|
|
||||||
"routes": "remix routes"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@code-hike/mdx": "0.9.0",
|
|
||||||
"@remix-run/node": "2.15.2",
|
|
||||||
"@remix-run/react": "2.15.2",
|
|
||||||
"@remix-run/serve": "2.15.2",
|
|
||||||
"codehike": "1.0.1",
|
|
||||||
"esbuild": "0.24.0",
|
|
||||||
"isbot": "5.1.17",
|
|
||||||
"mdx-bundler": "10.0.3",
|
|
||||||
"react": "18.3.1",
|
|
||||||
"react-dom": "18.3.1",
|
|
||||||
"react-icons": "5.3.0",
|
|
||||||
"remark-frontmatter": "^5.0.0",
|
|
||||||
"remark-mdx-frontmatter": "^5.0.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@biomejs/biome": "1.9.3",
|
|
||||||
"@mdx-js/rollup": "3.0.1",
|
|
||||||
"@remix-run/dev": "2.15.2",
|
|
||||||
"@tailwindcss/typography": "0.5.15",
|
|
||||||
"@types/react": "18.3.8",
|
|
||||||
"@types/react-dom": "18.3.0",
|
|
||||||
"autoprefixer": "10.4.20",
|
|
||||||
"postcss": "8.4.47",
|
|
||||||
"tailwindcss": "3.4.12",
|
|
||||||
"typescript": "5.6.2",
|
|
||||||
"vite": "5.4.7",
|
|
||||||
"vite-tsconfig-paths": "5.0.1"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
export default {
|
|
||||||
plugins: {
|
|
||||||
tailwindcss: {},
|
|
||||||
},
|
|
||||||
};
|
|
Binary file not shown.
Before Width: | Height: | Size: 83 KiB |
@ -1,5 +0,0 @@
|
|||||||
User-Agent: *
|
|
||||||
Allow: /
|
|
||||||
|
|
||||||
User-Agent: *
|
|
||||||
Allow: /blog
|
|
@ -1,20 +0,0 @@
|
|||||||
import type { Config } from "tailwindcss";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
content: ["./app/**/*.{ts,tsx}"],
|
|
||||||
theme: {
|
|
||||||
extend: {
|
|
||||||
animation: {
|
|
||||||
blink: "blink 1.5s linear infinite alternate",
|
|
||||||
},
|
|
||||||
|
|
||||||
keyframes: {
|
|
||||||
blink: {
|
|
||||||
"from, 49.9%": { opacity: "0" },
|
|
||||||
"to, 50%": { opacity: "1" },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
plugins: [require("@tailwindcss/typography")],
|
|
||||||
} satisfies Config;
|
|
@ -1,25 +0,0 @@
|
|||||||
{
|
|
||||||
"include": ["env.d.ts", "**/*.ts", "**/*.tsx"],
|
|
||||||
"compilerOptions": {
|
|
||||||
"lib": ["DOM", "DOM.Iterable", "ES2022"],
|
|
||||||
"isolatedModules": true,
|
|
||||||
"esModuleInterop": true,
|
|
||||||
"jsx": "react-jsx",
|
|
||||||
"skipLibCheck": true,
|
|
||||||
"module": "ESNext",
|
|
||||||
"moduleResolution": "Bundler",
|
|
||||||
"resolveJsonModule": true,
|
|
||||||
"target": "ES2022",
|
|
||||||
"strict": true,
|
|
||||||
"allowJs": true,
|
|
||||||
"forceConsistentCasingInFileNames": true,
|
|
||||||
"baseUrl": ".",
|
|
||||||
"paths": {
|
|
||||||
"~/*": ["./app/*"]
|
|
||||||
},
|
|
||||||
"types": ["./node_modules/@remix-run/react/future/single-fetch.d.ts"],
|
|
||||||
|
|
||||||
// Remix takes care of building everything in `remix build`.
|
|
||||||
"noEmit": true
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
import { remarkCodeHike } from "@code-hike/mdx";
|
|
||||||
import mdx from "@mdx-js/rollup";
|
|
||||||
import { vitePlugin as remix } from "@remix-run/dev";
|
|
||||||
import { defineConfig } from "vite";
|
|
||||||
import tsconfigPaths from "vite-tsconfig-paths";
|
|
||||||
|
|
||||||
declare module "@remix-run/node" {
|
|
||||||
interface Future {
|
|
||||||
v3_singleFetch: true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default defineConfig({
|
|
||||||
server: {
|
|
||||||
port: 3000,
|
|
||||||
},
|
|
||||||
plugins: [
|
|
||||||
mdx({
|
|
||||||
remarkPlugins: [[remarkCodeHike]],
|
|
||||||
}),
|
|
||||||
remix({
|
|
||||||
ignoredRouteFiles: ["**/*.css"],
|
|
||||||
future: {
|
|
||||||
v3_singleFetch: true,
|
|
||||||
v3_lazyRouteDiscovery: true,
|
|
||||||
v3_throwAbortReason: true,
|
|
||||||
v3_relativeSplatPath: true,
|
|
||||||
v3_fetcherPersist: true,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
tsconfigPaths(),
|
|
||||||
],
|
|
||||||
});
|
|
Loading…
x
Reference in New Issue
Block a user