{"id":23364482,"url":"https://github.com/fission-codes/nextjs-blog-starter-typescript-ghost","last_synced_at":"2025-04-10T12:52:31.799Z","repository":{"id":74436345,"uuid":"330688510","full_name":"fission-codes/nextjs-blog-starter-typescript-ghost","owner":"fission-codes","description":"Same as official nextjs-blog-starter-typescript, with added support for fetching content from Ghost via its API","archived":false,"fork":false,"pushed_at":"2021-02-26T11:04:56.000Z","size":428,"stargazers_count":16,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-03T04:56:18.287Z","etag":null,"topics":["fission","fission-suite","ghost","ghost-api","ghost-blog","ghost-cms","headless-cms","headless-ghost","jamstack","nextjs","nextjs-starter"],"latest_commit_sha":null,"homepage":"https://blog.fission.codes/headless-ghost-blog-fission/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fission-codes.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2021-01-18T14:17:42.000Z","updated_at":"2023-10-19T15:22:29.000Z","dependencies_parsed_at":"2023-02-26T18:15:56.165Z","dependency_job_id":null,"html_url":"https://github.com/fission-codes/nextjs-blog-starter-typescript-ghost","commit_stats":null,"previous_names":[],"tags_count":0,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fission-codes%2Fnextjs-blog-starter-typescript-ghost","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fission-codes%2Fnextjs-blog-starter-typescript-ghost/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fission-codes%2Fnextjs-blog-starter-typescript-ghost/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fission-codes%2Fnextjs-blog-starter-typescript-ghost/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fission-codes","download_url":"https://codeload.github.com/fission-codes/nextjs-blog-starter-typescript-ghost/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248132061,"owners_count":21052970,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fission","fission-suite","ghost","ghost-api","ghost-blog","ghost-cms","headless-cms","headless-ghost","jamstack","nextjs","nextjs-starter"],"created_at":"2024-12-21T13:16:27.881Z","updated_at":"2025-04-10T12:52:31.777Z","avatar_url":"https://github.com/fission-codes.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 👻\u0026nbsp;\u0026nbsp;Headless Ghost with Next.js on Fission\n\n- [👻\u0026nbsp;\u0026nbsp;Headless Ghost with Next.js on Fission](#headless-ghost-with-nextjs-on-fission)\n  - [✨\u0026nbsp;\u0026nbsp;Getting Started](#getting-started)\n    - [👻\u0026nbsp;\u0026nbsp;Setting Up Ghost](#setting-up-ghost)\n      - [Cloud or Local Ghost?](#cloud-or-local-ghost)\n      - [Setting Up Local Ghost](#setting-up-local-ghost)\n      - [Setting Up Cloud Ghost](#setting-up-cloud-ghost)\n      - [Exposing the Ghost Content API](#exposing-the-ghost-content-api)\n    - [💻\u0026nbsp;\u0026nbsp;Running Next.js Locally](#running-nextjs-locally)\n    - [🌐\u0026nbsp;\u0026nbsp;Deploying to Fission](#deploying-to-fission)\n      - [🔰\u0026nbsp;\u0026nbsp;Fission CLI Install and Sign Up](#fission-cli-install-and-sign-up)\n      - [🌱\u0026nbsp;\u0026nbsp;Register New Fission App](#register-new-fission-app)\n      - [🚀 \u0026nbsp;\u0026nbsp;Aand... Launch!](#-aand-launch)\n      - [🤖\u0026nbsp;\u0026nbsp;(Semi-)Automatic Deployment with the GitHub Action](#semi-automatic-deployment-with-the-github-action)\n  - [🙏\u0026nbsp;\u0026nbsp;Show your support](#show-your-support)\n  - [📝\u0026nbsp;\u0026nbsp;License](#license)\n\n---\n\nThis starter is based on the official\n[blog-starter-typescript](https://github.com/vercel/next.js/tree/canary/examples/blog-starter-typescript)\nfrom [Next.js](https://nextjs.org).\n\nWe changed it only enough to make it possible to fetch and publish blog posts\nfrom the Ghost CMS, while keeping the ability to write Markdown files in the\ngit repo. It's a purely additive change.\n\nThere's also a GitHub Action to build and publish the static website to\nFission. It works automatically on pushes to the git repo, and can be triggered\nmanually after updating the content on Ghost. (The default Ghost webhook isn't\ncustomizable to trigger a GitHub Action, but that can be added as a plugin.)\n\nThe Markdown blog posts are stored in `/_posts` as files with frontmatter\nsupport. Adding a new Markdown file in there will create a new blog post.\n\nThe Ghost blog posts are fetched using Ghost's Content API library.\n\n## ✨\u0026nbsp;\u0026nbsp;Getting Started\n\nLet's start by making this starter yours:\n\n- Click **Use this template** at the\n  [starter page on GitHub](https://github.com/fission-suite/nextjs-blog-starter-typescript-ghost)\n\n  That will make a copy of the starter into a new repo under your account with\n  a fresh git history. You can pick a different name for it too; in that case\n  replace `nextjs-blog-starter-typescript-ghost` with your chosen name below.\n\n- Clone the repo (replace with your own URL):\n  ```\n  git clone git@github.com:fission-suite/nextjs-blog-starter-typescript-ghost.git\n  ```\n- cd into the repo:\n  ```\n  cd nextjs-blog-starter-typescript-ghost\n  ```\n- Install dependencies\n  ```\n  yarn\n  ```\n\nAll command-line instructions and directory paths from now on assume the\ncurrent directory is the root of the cloned repo.\n\n### 👻\u0026nbsp;\u0026nbsp;Setting Up Ghost\n\n#### Cloud or Local Ghost?\n\nRunning a local Ghost instance is good for testing. But also, if you have no\nneed for a Ghost instance running all the time out on the internet (for\nexample, if you are the only author) you can do this for your production\nwebsite, using Ghost locally for its nice interface if you prefer that to\nediting Markdown files. No servers to secure, no bills to pay.\n\n#### Setting Up Local Ghost\n\nIf you have a Ghost instance running already somewhere, move on to the next\nstep. If you don't, you can set one up on your own machine with Docker.\n\nTo create a local Ghost instance with Docker, run the following at the root of\nyour repo:\n\n```bash\nyarn ghost-local-create\n```\n\nGhost data will be stored at `./ghost`, which is in `.gitignore` by default. In\na **private** repo you can choose to commit that too and have your Ghost\ncontent versioned and available whenever you need it.\n\nThere are other scripts like `ghost-local-start`, `ghost-local-stop`, and\n`ghost-local-remove` which you might find handy to manage the Docker container.\n\nAfter Docker downloads and sets up Ghost, it will be accessible on your browser\nat http://localhost:3001.\n\nNext you need to create an admin account on your newly-created Ghost. To do\nthat, visit the admin interface at http://localhost:3001/ghost and follow the\nwizard.\n\n#### Setting Up Cloud Ghost\n\n![Screencast demoing deployment to Heroku](https://github.com/agentofuser/gifs/raw/main/fission/fission-heroku-ipfs-ghost-2x.gif)\n\nYou can deploy a Ghost instance to Heroku using Fission's own starter (it's\nwhat we use for our blog) at\nhttps://github.com/fission-suite/heroku-ipfs-ghost.\n\nBesides being a very low-friction and zero-cost way to get started with Ghost,\nour starter comes with built-in support for hosting media files on IPFS via\nFission, no extra configuration required.\n\n#### Exposing the Ghost Content API\n\nI'll use `http://localhost:3001` for the examples, but you can replace that\nwith your Ghost URL if you have an instance already running somewhere else.\n\n- Go to the admin interface at http://localhost:3001/ghost\n- On the left-hand sidebar, click on \"Integrations\"\n- On the Integrations screen, click on\n  [+Add custom integration](http://localhost:3001/ghost/#/settings/integrations/new/)\n- Give it a name, like `nextjs`, and click \"Create\" then \"Save\"\n\nNow the important part:\n\n- On the same screen, you'll find two fields we need: **Content API Key** and\n  **API URL**\n- Copy those into a new `.env.local` file, like this:\n\n```bash\n# .env.local\n# replace values with your own\nGHOST_API_URL=http://localhost:3001\nGHOST_API_KEY=2a9356e4a5214c883ba886e58e\n```\n\n⚠️ _This file is ignored by git by default. **Don't** commit `env.local` to git\nunless you know what you're doing._\n\nAlright! Ghost part's done.\n\n### 💻\u0026nbsp;\u0026nbsp;Running Next.js Locally\n\nNext.js is the missing static website _head_ to our *head*less Ghost. Let's\nstitch them together! This should be enough:\n\n```bash\nyarn dev\n```\n\nYour blog should be up and running at\n[http://localhost:3000](http://localhost:3000)! _(If anything unexpected\nhappens, please post an\n[issue](https://github.com/fission-suite/nextjs-blog-starter-typescript-ghost/issues/new).)_\n\nNow you can change the Next.js website code and the content on Ghost, and\niterate quickly on them in the browser.\n\n_Note: live-reload works for Next.js code and Markdown files; to see changes to\nGhost content you need to refresh the page._\n\n### 🌐\u0026nbsp;\u0026nbsp;Deploying to Fission\n\nWhen you're ready to publish, the first step is exporting your website to a set\nof static files:\n\n```bash\nyarn build\n```\n\nThat should create a directory at `./out` with all your ready-to-publish files.\n\nNext we use the Fission CLI to send that out onto the internets.\n\n#### 🔰\u0026nbsp;\u0026nbsp;Fission CLI Install and Sign Up\n\nTo install the Fission command-line interface using brew, run:\n\n```bash\nbrew tap fission-suite/fission\nbrew install fission-cli\n```\n\nFor more ways of installing the Fission CLI, please check the\n[documentation](https://guide.fission.codes/developers/installation).\n\nIf you don't have a Fission account, you can create one without leaving the\ncommand-line by running:\n\n```bash\nfission setup\n```\n\n#### 🌱\u0026nbsp;\u0026nbsp;Register New Fission App\n\nYou can pick a subdomain or let Fission choose a random one for you.\n\nTo host the Next.js website at a random subdomain on `.fission.app`, run:\n\n```bash\nfission app register\n```\n\nTo choose your own subdomain, use the `--name` option like this:\n\n```bash\nfission app register --name my-beautiful-subdomain\n```\n\nThat will create a `fission.yaml` file. **This one is safe to commit to git**,\nand you _should_ do that if you want to use the GitHub Action to build and\ndeploy the website for you. Make sure there is a line saying `build: ./out` in\nit. That's the directory where Next.js puts the exported website files.\n\n#### 🚀 \u0026nbsp;\u0026nbsp;Aand... Launch!\n\nOne last step:\n\n```bash\nfission app publish\n```\n\nAnd you're done! Your website should be up at a random URL returned to you by\nthe Fission CLI or at `my-beautiful-subdomain.fission.app` if you used the\n`--name` option. Yay!\n\n#### 🤖\u0026nbsp;\u0026nbsp;(Semi-)Automatic Deployment with the GitHub Action\n\nIf you don't want to run the build locally and deploy to Fission every time you\nmake a change to the Next.js code or Markdown files (who does?), this starter\ncomes with **a GitHub Action that automates that for you**.\n\nTo get it working you need to set up 3 secrets for your repo. To do that, go to\nthe **\"Settings\" \u003e \"Secrets\"** screen on your GitHub repo, then create a **\"New\nrepository secret\"** for each of these:\n\n- `GHOST_API_URL`\n- `GHOST_API_KEY`\n- `FISSION_KEY`\n\nThe values for the `GHOST_API_` fields are the same ones you used for the\n`.env.local` file above.\n\nThe `FISSION_KEY` was created and stored locally for you by the Fission CLI\nwhen you set it up. Here's how you get it:\n\n```\ncat ~/.config/fission/key/machine_id.ed25519 | base64\n```\n\nWith all 3 secrets set up, you can trigger the `deploy` action manually by\nclicking on **\"Run workflow\" \u003e \"Run workflow\"**, or see it in action after your\nnext `git push`.\n\n---\n\nNote:\n\n⚠️\u0026nbsp;\u0026nbsp;To fetch the content from Ghost, **the GitHub Action must be able\nto access the URL** entered in the `GHOST_API_URL` secret.\n\nIf you are running a local Ghost instance on your machine,\n`http://localhost:3001` won't be visible to the outside.\n\nA simple way of exposing your local Ghost instance to a publicly-reachable URL\nis by using one of the\n[open source alternatives to ngrok](https://github.com/anderspitman/awesome-tunneling)\nor [ngrok](https://ngrok.com/) itself.\n\nWith ngrok you do something like this:\n\n```\nngrok http 3001\n```\n\n⚠️\u0026nbsp;\u0026nbsp;This is great for testing, but **not secure**. Look into using\n`https` if you're going to rely on this and don't want your Ghost API key and\ndata to leak.\n\n---\n\n\u003e Why **\"(semi-)**\" automatic then? 🤔\n\nGlad you asked. The GitHub Action can detect when you push to the GitHub repo\nbecause **there's a built-in \"on push\" event** that can be used to **trigger**\nit.\n\nBut when you create a new post on Ghost or update an existing one, GitHub needs\na way of finding out about it so it can run the deploy action. There's no\n`git push` event happening, so the trigger is usually a\n[**webhook**](https://docs.github.com/en/rest/reference/actions#create-a-workflow-dispatch-event)\n(i.e. a POST request you send to a GitHub API URL.)\n\n🙂\u0026nbsp;\u0026nbsp;Luckily, Ghost comes with the built-in ability to send webhooks\nwhen content changes happen.\n\n🙃\u0026nbsp;\u0026nbsp;***Un*luckily**, though, Ghost doesn't let you customize the\npayload that goes in the webhook requests it sends, and GitHub **requires** a\ncertain field to be present telling it which `ref` (usually a branch) you are\nreferring to.\n\nBottom line: **after changing things _on Ghost_, you need to trigger a build\nmanually**.\n\nYou can do that via the GitHub interface (\"Actions\" \u003e \"Continuous Deployment\" \u003e\n\"Run workflow\" \u003e \"Run workflow\"), or by **running the handy script** we added\nto this starter:\n\n```\nGITHUB_USER=your-username GITHUB_REPO=your-repo GITHUB_AUTH_TOKEN=your-auth-token trigger-github-deploy-action.sh\n```\n\nHere's how you can get an\n[auth token](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token).\n\nThis situation is definitely not ideal, and can be solved with Ghost plugins,\nbut we wanted to stick to the basic install.\n\n## 🙏\u0026nbsp;\u0026nbsp;Show your support\n\nPlease give a\u0026nbsp;\u0026nbsp;⭐️\u0026nbsp;\u0026nbsp;if you liked this project! We\nappreciate it :)\n\n## 📝\u0026nbsp;\u0026nbsp;License\n\n\u003csup\u003e\nLicensed under either of \u003ca href=\"LICENSE-APACHE\"\u003eApache License, Version\n2.0\u003c/a\u003e or \u003ca href=\"LICENSE-MIT\"\u003eMIT license\u003c/a\u003e at your option.\n\u003c/sup\u003e\n\n\u003cbr\u003e\n\n\u003csub\u003e\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in this crate by you, as defined in the Apache-2.0 license, shall\nbe dual licensed as above, without any additional terms or conditions.\n\u003c/sub\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffission-codes%2Fnextjs-blog-starter-typescript-ghost","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffission-codes%2Fnextjs-blog-starter-typescript-ghost","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffission-codes%2Fnextjs-blog-starter-typescript-ghost/lists"}