<br />
<b>Deprecated</b>:  The each() function is deprecated. This message will be suppressed on further calls in <b>/home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php</b> on line <b>456</b><br />
{
    "version": "https://jsonfeed.org/version/1",
    "title": "Articles by François Best",
    "home_page_url": "https://francoisbest.com/posts",
    "feed_url": "https://francoisbest.com/posts/feed/articles.json",
    "description": "I write about TypeScript, Node.js, React, security and privacy.",
    "icon": "https://francoisbest.com/favicons/apple-icon-120x120.png",
    "author": {
        "name": "François Best",
        "url": "https://francoisbest.com/"
    },
    "items": [
        {
            "id": "/posts/2023/testing-against-every-nextjs-canary-release",
            "content_html": "How to run a GitHub Actions workflow when a new pre-release version of Next.js is published.\n\n<a href=\"https://francoisbest.com/posts/2023/testing-against-every-nextjs-canary-release?utm_source=json\">Full article</a> (6 min read).",
            "url": "https://francoisbest.com/posts/2023/testing-against-every-nextjs-canary-release?utm_source=json",
            "title": "Testing against every Next.js canary release",
            "summary": "How to run a GitHub Actions workflow when a new pre-release version of Next.js is published.",
            "image": "https://francoisbest.com/posts/og/2023/testing-against-every-nextjs-canary-release",
            "date_modified": "2023-11-06T00:00:00.000Z",
            "date_published": "2023-11-06T00:00:00.000Z",
            "author": {
                "name": "François Best",
                "url": "https://francoisbest.com/"
            },
            "tags": [
                "next.js",
                "github-actions",
                "testing"
            ]
        },
        {
            "id": "/posts/2023/publish-a-json-schema",
            "content_html": "Improving DX in editors is only half the story.\n\n<a href=\"https://francoisbest.com/posts/2023/publish-a-json-schema?utm_source=json\">Full article</a> (3 min read).",
            "url": "https://francoisbest.com/posts/2023/publish-a-json-schema?utm_source=json",
            "title": "Publish a JSON Schema",
            "summary": "Improving DX in editors is only half the story.",
            "image": "https://francoisbest.com/posts/og/2023/publish-a-json-schema",
            "date_modified": "2023-10-12T00:00:00.000Z",
            "date_published": "2023-10-12T00:00:00.000Z",
            "author": {
                "name": "François Best",
                "url": "https://francoisbest.com/"
            },
            "tags": [
                "json-schema",
                "nodejs"
            ]
        },
        {
            "id": "/posts/2023/dotenv-is-dead",
            "content_html": "Long live type-safe environment variable management in Node.js\n\n<a href=\"https://francoisbest.com/posts/2023/dotenv-is-dead?utm_source=json\">Full article</a> (3 min read).",
            "url": "https://francoisbest.com/posts/2023/dotenv-is-dead?utm_source=json",
            "title": "Dotenv is dead",
            "summary": "Long live type-safe environment variable management in Node.js",
            "image": "https://francoisbest.com/posts/og/2023/dotenv-is-dead",
            "date_modified": "2023-10-02T00:00:00.000Z",
            "date_published": "2023-10-02T00:00:00.000Z",
            "author": {
                "name": "François Best",
                "url": "https://francoisbest.com/"
            },
            "tags": [
                "til",
                "nodejs",
                "env"
            ]
        },
        {
            "id": "/posts/2023/displaying-local-times-in-nextjs",
            "content_html": "Making time accessible by dealing with React SSR hydration mismatches across timezones.\n\n<a href=\"https://francoisbest.com/posts/2023/displaying-local-times-in-nextjs?utm_source=json\">Full article</a> (4 min read).",
            "url": "https://francoisbest.com/posts/2023/displaying-local-times-in-nextjs?utm_source=json",
            "title": "Displaying Local Times in Next.js",
            "summary": "Making time accessible by dealing with React SSR hydration mismatches across timezones.",
            "image": "https://francoisbest.com/posts/og/2023/displaying-local-times-in-nextjs",
            "date_modified": "2023-09-27T08:00:00.000Z",
            "date_published": "2023-09-27T08:00:00.000Z",
            "author": {
                "name": "François Best",
                "url": "https://francoisbest.com/"
            },
            "tags": [
                "til",
                "next.js",
                "react",
                "ssr",
                "rsc"
            ]
        },
        {
            "id": "/posts/2023/npm-download-stats-are-down",
            "content_html": "And people are drawing the funniest conclusions.\n\n<a href=\"https://francoisbest.com/posts/2023/npm-download-stats-are-down?utm_source=json\">Full article</a> (2 min read).",
            "url": "https://francoisbest.com/posts/2023/npm-download-stats-are-down?utm_source=json",
            "title": "NPM download stats are down",
            "summary": "And people are drawing the funniest conclusions.",
            "image": "https://francoisbest.com/posts/og/2023/npm-download-stats-are-down",
            "date_modified": "2023-09-21T00:00:00.000Z",
            "date_published": "2023-09-21T00:00:00.000Z",
            "author": {
                "name": "François Best",
                "url": "https://francoisbest.com/"
            },
            "tags": [
                "npm"
            ]
        },
        {
            "id": "/posts/2023/storing-react-state-in-the-url-with-nextjs",
            "content_html": "A peek under the hood of the next-usequerystate 1.8.x update with support for the app router.\n\n<a href=\"https://francoisbest.com/posts/2023/storing-react-state-in-the-url-with-nextjs?utm_source=json\">Full article</a> (7 min read).",
            "url": "https://francoisbest.com/posts/2023/storing-react-state-in-the-url-with-nextjs?utm_source=json",
            "title": "Storing React state in the URL with Next.js",
            "summary": "A peek under the hood of the next-usequerystate 1.8.x update with support for the app router.",
            "image": "https://francoisbest.com/posts/og/2023/storing-react-state-in-the-url-with-nextjs",
            "date_modified": "2023-09-20T00:00:00.000Z",
            "date_published": "2023-09-20T00:00:00.000Z",
            "author": {
                "name": "François Best",
                "url": "https://francoisbest.com/"
            },
            "tags": [
                "next.js",
                "react",
                "typescript"
            ]
        },
        {
            "id": "/posts/2023/reading-files-on-vercel-during-nextjs-isr",
            "content_html": "A little hack to let the Next.js file tracer pick up relative file paths.\n\n<a href=\"https://francoisbest.com/posts/2023/reading-files-on-vercel-during-nextjs-isr?utm_source=json\">Full article</a> (2 min read).",
            "url": "https://francoisbest.com/posts/2023/reading-files-on-vercel-during-nextjs-isr?utm_source=json",
            "title": "Reading files on Vercel during Next.js ISR",
            "summary": "A little hack to let the Next.js file tracer pick up relative file paths.",
            "image": "https://francoisbest.com/posts/og/2023/reading-files-on-vercel-during-nextjs-isr",
            "date_modified": "2023-09-16T00:00:00.000Z",
            "date_published": "2023-09-16T00:00:00.000Z",
            "author": {
                "name": "François Best",
                "url": "https://francoisbest.com/"
            },
            "tags": [
                "til",
                "next.js",
                "vercel",
                "rsc"
            ]
        },
        {
            "id": "/posts/2023/displaying-the-right-vercel-deployment-urls-in-nextjs",
            "content_html": "A TIL about caching, Git branch management and React Server Components.\n\n<a href=\"https://francoisbest.com/posts/2023/displaying-the-right-vercel-deployment-urls-in-nextjs?utm_source=json\">Full article</a> (4 min read).",
            "url": "https://francoisbest.com/posts/2023/displaying-the-right-vercel-deployment-urls-in-nextjs?utm_source=json",
            "title": "Displaying the right Vercel deployment URLs in Next.js",
            "summary": "A TIL about caching, Git branch management and React Server Components.",
            "image": "https://francoisbest.com/posts/og/2023/displaying-the-right-vercel-deployment-urls-in-nextjs",
            "date_modified": "2023-09-09T00:00:00.000Z",
            "date_published": "2023-09-09T00:00:00.000Z",
            "author": {
                "name": "François Best",
                "url": "https://francoisbest.com/"
            },
            "tags": [
                "til",
                "rsc",
                "git",
                "next.js",
                "turborepo",
                "vercel"
            ]
        },
        {
            "id": "/posts/2021/hashvatars",
            "content_html": "How to turn 256 bits of entropy into a beautiful, avatar-friendly circular SVG: the Hashvatar.\n\n<a href=\"https://francoisbest.com/posts/2021/hashvatars?utm_source=json\">Full article</a> (12 min read).",
            "url": "https://francoisbest.com/posts/2021/hashvatars?utm_source=json",
            "title": "Representing SHA-256 Hashes As Avatars",
            "summary": "How to turn 256 bits of entropy into a beautiful, avatar-friendly circular SVG: the Hashvatar.",
            "image": "https://francoisbest.com/posts/og/2021/hashvatars",
            "date_modified": "2021-04-18T00:00:00.000Z",
            "date_published": "2021-04-18T00:00:00.000Z",
            "author": {
                "name": "François Best",
                "url": "https://francoisbest.com/"
            },
            "tags": [
                "cryptography",
                "svg"
            ]
        },
        {
            "id": "/posts/2021/cargo-docker-mtime",
            "content_html": "The perils of premature optimisation in detecting modified source files when building Docker images for Rust.\n\n<a href=\"https://francoisbest.com/posts/2021/cargo-docker-mtime?utm_source=json\">Full article</a> (4 min read).",
            "url": "https://francoisbest.com/posts/2021/cargo-docker-mtime?utm_source=json",
            "title": "Cargo, Docker and mtime",
            "summary": "The perils of premature optimisation in detecting modified source files when building Docker images for Rust.",
            "image": "https://francoisbest.com/posts/og/2021/cargo-docker-mtime",
            "date_modified": "2021-01-25T00:00:00.000Z",
            "date_published": "2021-01-25T00:00:00.000Z",
            "author": {
                "name": "François Best",
                "url": "https://francoisbest.com/"
            },
            "tags": [
                "rust",
                "docker"
            ]
        },
        {
            "id": "/posts/2020/mobile-device-frames-for-excalidraw",
            "content_html": "Building mobile UI mockups in Excalidraw is a lot of fun, but eye-balling screen ratios is not great. Here are some free resources to help you get started, and a guide on how to make your own frames.\n\n<a href=\"https://francoisbest.com/posts/2020/mobile-device-frames-for-excalidraw?utm_source=json\">Full article</a> (3 min read).",
            "url": "https://francoisbest.com/posts/2020/mobile-device-frames-for-excalidraw?utm_source=json",
            "title": "Mobile Device Frames For Excalidraw",
            "summary": "Building mobile UI mockups in Excalidraw is a lot of fun, but eye-balling screen ratios is not great. Here are some free resources to help you get started, and a guide on how to make your own frames.",
            "image": "https://francoisbest.com/posts/og/2020/mobile-device-frames-for-excalidraw",
            "date_modified": "2020-06-11T00:00:00.000Z",
            "date_published": "2020-06-11T00:00:00.000Z",
            "author": {
                "name": "François Best",
                "url": "https://francoisbest.com/"
            },
            "tags": [
                "excalidraw",
                "ui-design"
            ]
        },
        {
            "id": "/posts/2020/dark-mode-for-excalidraw",
            "content_html": "How to give a dark twist to Excalidraw diagrams with CSS filters.\n\n<a href=\"https://francoisbest.com/posts/2020/dark-mode-for-excalidraw?utm_source=json\">Full article</a> (3 min read).",
            "url": "https://francoisbest.com/posts/2020/dark-mode-for-excalidraw?utm_source=json",
            "title": "Dark Mode For Excalidraw",
            "summary": "How to give a dark twist to Excalidraw diagrams with CSS filters.",
            "image": "https://francoisbest.com/posts/og/2020/dark-mode-for-excalidraw",
            "date_modified": "2020-06-05T00:00:00.000Z",
            "date_published": "2020-06-05T00:00:00.000Z",
            "author": {
                "name": "François Best",
                "url": "https://francoisbest.com/"
            },
            "tags": [
                "frontend",
                "css",
                "excalidraw"
            ]
        },
        {
            "id": "/posts/2020/the-security-of-github-actions",
            "content_html": "GitHub Actions are a great way to build powerful customised CI/CD workflows using the power of community-driven resources, but they can be tricky to get right in terms of security.\n\n<a href=\"https://francoisbest.com/posts/2020/the-security-of-github-actions?utm_source=json\">Full article</a> (9 min read).",
            "url": "https://francoisbest.com/posts/2020/the-security-of-github-actions?utm_source=json",
            "title": "The Security of GitHub Actions",
            "summary": "GitHub Actions are a great way to build powerful customised CI/CD workflows using the power of community-driven resources, but they can be tricky to get right in terms of security.",
            "image": "https://francoisbest.com/posts/og/2020/the-security-of-github-actions",
            "date_modified": "2020-02-24T00:00:00.000Z",
            "date_published": "2020-02-24T00:00:00.000Z",
            "author": {
                "name": "François Best",
                "url": "https://francoisbest.com/"
            },
            "tags": [
                "security",
                "tooling",
                "github-actions",
                "docker"
            ]
        },
        {
            "id": "/posts/2020/password-reset-for-e2ee-apps",
            "content_html": "We forget passwords. Usually it's OK, because most websites implement a password reset feature. But how to do this in end-to-end encrypted applications that don't have access to the password in the first place ?\n\n<a href=\"https://francoisbest.com/posts/2020/password-reset-for-e2ee-apps?utm_source=json\">Full article</a> (5 min read).",
            "url": "https://francoisbest.com/posts/2020/password-reset-for-e2ee-apps?utm_source=json",
            "title": "Password Reset for End-to-End Encrypted Applications",
            "summary": "We forget passwords. Usually it's OK, because most websites implement a password reset feature. But how to do this in end-to-end encrypted applications that don't have access to the password in the first place ?",
            "image": "https://francoisbest.com/posts/og/2020/password-reset-for-e2ee-apps",
            "date_modified": "2020-02-15T00:00:00.000Z",
            "date_published": "2020-02-15T00:00:00.000Z",
            "author": {
                "name": "François Best",
                "url": "https://francoisbest.com/"
            },
            "tags": [
                "e2ee",
                "security",
                "cryptography"
            ]
        },
        {
            "id": "/posts/2019/how-to-store-e2ee-keys-in-the-browser",
            "content_html": "End-to-end encrypted applications use cryptographic keys that don't leave the client, so how do we store them securely in the browser ?\n\n<a href=\"https://francoisbest.com/posts/2019/how-to-store-e2ee-keys-in-the-browser?utm_source=json\">Full article</a> (4 min read).",
            "url": "https://francoisbest.com/posts/2019/how-to-store-e2ee-keys-in-the-browser?utm_source=json",
            "title": "How To Store End-to-End Encryption Keys In The Browser",
            "summary": "End-to-end encrypted applications use cryptographic keys that don't leave the client, so how do we store them securely in the browser ?",
            "image": "https://francoisbest.com/posts/og/2019/how-to-store-e2ee-keys-in-the-browser",
            "date_modified": "2019-12-13T00:00:00.000Z",
            "date_published": "2019-12-13T00:00:00.000Z",
            "author": {
                "name": "François Best",
                "url": "https://francoisbest.com/"
            },
            "tags": [
                "e2ee",
                "security"
            ]
        },
        {
            "id": "/posts/2019/strava-auth-cli-in-rust",
            "content_html": "A first look at how to implement an OAuth authentication / authorization exchange in Rust.\n\n<a href=\"https://francoisbest.com/posts/2019/strava-auth-cli-in-rust?utm_source=json\">Full article</a> (14 min read).",
            "url": "https://francoisbest.com/posts/2019/strava-auth-cli-in-rust?utm_source=json",
            "title": "Building A Strava Authentication CLI In Rust",
            "summary": "A first look at how to implement an OAuth authentication / authorization exchange in Rust.",
            "image": "https://francoisbest.com/posts/og/2019/strava-auth-cli-in-rust",
            "date_modified": "2019-01-15T00:00:00.000Z",
            "date_published": "2019-01-15T00:00:00.000Z",
            "author": {
                "name": "François Best",
                "url": "https://francoisbest.com/"
            },
            "tags": [
                "rust",
                "strava"
            ]
        }
    ]
}