Notify users of your Next.js app when a new deploy is available.

Overview

Next.js Deploy Notifications

This library lets your users know when you've deployed a new version of your Next.js application.

import { hasNewDeploy } from 'next-deploy-notifications';

function App() {
  let hasNewDeploy = useHasNewDeploy();

  return (
    <div>
      <main>Your app</main>

      {hasNewDeploy && (
        <Notification>
          New version available!
          <button onClick={() => window.location.reload()}>Refresh</button>
        </Notification>
      )}
    </div>
  );
}

Deploy notification

Installation

npm install next-deploy-notifications

# or

yarn add next-deploy-notifications

Setup

API Route

You'll first need to create a new API route in order for this library to work correctly. Paste the following into pages/api/has-new-deploy.js.

// pages/api/has-new-deploy.js

export { APIRoute as default } from 'next-deploy-notifications';

Usage

Next, the useHasNewDeploy hook will tell you when a new version of your application has been deployed. This hook returns a boolean that's true when there's a new deploy.

import { useHasNewDeploy } from 'next-deploy-notifications';

function Page() {
  let hasNewDeploy = useHasNewDeploy();

  return hasNewDeploy && <div>A new deploy is available!</div>;
}

Production environments

This add works out of the box with the following hosting providers:

  • Vercel

    Note: Make sure you're application has "Automatically expose System Environment Variables" checked. This can be found in the Vercel dashboard under Settings > Environment variables.

Other hosts

Coming soon.

Comments
  • type-script api error

    type-script api error

    // pages/api/has-new-deploy.ts
    
    import { APIRoute } from 'next-deploy-notifications';
    
    export default APIRoute.configure({
      version: () =>
        process.env.NEXT_BUILD_ID || process.env.VERCEL_GIT_COMMIT_SHA || '',
    });
    
    

    This will cause the endpoint fail.

    If I change the import to `import { APIRoute } from 'next-deploy-notifications/api'

    A type error occurs

    Cannot find module 'next-deploy-notifications/api' or its corresponding type declarations.

    How do I fix it?

    opened by zhex900 5
  • Add support for the hosting provider Render.com

    Add support for the hosting provider Render.com

    This PR adds support for Render.com.

    When deployed to a Render environment, this package will now identify the current version by looking for RENDER and RENDER_GIT_COMMIT environment variables. All Render environments expose the RENDER variable as true and the RENDER_GIT_COMMIT will be the latest git commit hash for the given deploy.

    Let me know if I can do anything else to help out. I've never developed/contributed to a TS library before so I may have missed something important.

    Cheers

    opened by danielmichaels 2
  • Add support for Render.com

    Add support for Render.com

    Hey there,

    This is a great library, thanks a lot for putting this together.

    Is it possible to add support for Render.com?

    The two environment variables that would make this supported out of the box (like vercel) are RENDER_GIT_COMMIT and RENDER

    See the docs.

    My first impressions would be to create:

    let isRender: IsEnvironment = () => !!process.env.RENDER;
    let getRenderVersion: GetVersion = () => `${process.env.RENDER_GIT_COMMIT}`;
    

    and then reference them in the handler like so:

    let makeRouteHandler = (options: Options = {}): Handler => {
      let route: NextRouteHandler = async (req, res) => {
        let findVersion = options.version
          ? options.version()
          : isVercel()
          ? getVercelVersion()
          : isRender() # untested
          ? getRenderVersion() # untested
          : isGit()
          ? getGitVersion()
          : getUnknownVersion();
        let version = await Promise.resolve(findVersion);
        res.status(200).json({ version });
      };
    

    I am happy to open a PR for this if it's a viable option.

    Cheers

    opened by danielmichaels 2
  • Content update no commit change

    Content update no commit change

    Hi,

    How can I trigger a new deploy notification when there is a content update? I am using graphCMS for content management. The site is a static site. For content changes, the Vercel will trigger a rebuild. But rebuild will have the same commit hash.

    https://vercel.com/docs/concepts/projects/environment-variables

    I can use the BUILD_ID as a part of the site version.

    This is what I did

    I have added this to package.json "postbuild": "next-sitemap; echo NEXT_BUILD_ID=$(cat .next/BUILD_ID) > .env.production; cat .env.production"

    // pages/api/has-new-deploy.js
    import { APIRoute } from 'next-deploy-notifications/api';
    
    export default APIRoute.configure({
      version: () =>
        process.env.NEXT_BUILD_ID || process.env.VERCEL_GIT_COMMIT_SHA || '',
    });
    
    
    opened by zhex900 0
  • 500 error when there's no commits yet

    500 error when there's no commits yet

    Thanks for creating this really helpful package 👏🏻👏🏻👏🏻

    I have a little annoyance with it as it keeps erroring with status code 500 when I'm working and hasn't done a commit yet. CleanShot 2022-09-13 at 11 29 43

    As soon as I do my first git commit, the 500 errors disappears. Any way to work around this?

    My endpoint looks like this:

    export { APIRoute as default } from 'next-deploy-notifications/api';
    
    opened by mellson 0
  • Hook triggers unnecessary renderings (fix provided)

    Hook triggers unnecessary renderings (fix provided)

    Every time the interval is executed or the window gets focused or blurred the entire app re-renders. I fixed the hook but don't have any time to create a PR. If you find any issues in my code, please leave a comment. With my code you can also remove 2 dependencies.

    Feel free to use it:

    import {
      useCallback,
      useEffect,
      useRef,
      useState,
    } from 'react';
    
    const getCurrentVersion = async (endpoint: string) => {
      const response = await fetch(endpoint);
      if (response.status > 400) {
        console.error(
          '[next-deploy-notifications] Could not find current app version. Did you setup the API route?',
        );
        return { version: 'unknown' };
      }
      const json = await response.json();
      return json;
    };
    
    type HookOptions = {
      interval?: number;
      endpoint?: string;
      debug?: boolean;
    };
    
    type HookValues = {
      hasNewDeploy: boolean;
      version: string;
    };
    
    type UseHasNewDeploy = (options?: HookOptions) => HookValues;
    
    const useHasNewDeploy: UseHasNewDeploy = (options = {}) => {
      const debug = useCallback((message: string) => {
        if (options.debug) {
          console.log(...['[Deploy notifications] ', message]);
        }
      }, [options.debug]);
    
      const [hasNewDeploy, setHasNewDeploy] = useState<boolean>(false);
      const [currentVersion, setCurrentVersion] = useState<string>('unknown');
      const lastFetchedRef = useRef<number>();
      const intervalInstanceRef = useRef<NodeJS.Timer>();
      const windowFocused = useRef<boolean>(true);
    
      const interval = options.interval ?? 30_000;
      const loopInterval = interval < 3_000 ? interval : 3_000;
      const endpoint = options.endpoint ?? '/api/has-new-deploy';
      const isUnknown = currentVersion === 'unknown';
    
      const startInterval = useCallback(
        () => setInterval(async () => {
          debug('Looping...');
    
          const enoughTimeHasPassed =
          !lastFetchedRef.current || Date.now() >= lastFetchedRef.current + interval;
    
          if (enoughTimeHasPassed && !isUnknown) {
            debug('Fetching version');
            const { version } = await getCurrentVersion(endpoint);
            debug(`Version ${version}`);
    
            if (currentVersion !== version) {
              debug('Found new deploy');
              setHasNewDeploy(true);
              setCurrentVersion(version);
            }
    
            lastFetchedRef.current = Date.now();
          }
        }, loopInterval),
        [currentVersion, debug, endpoint, interval, isUnknown, loopInterval],
      );
    
      useEffect(() => {
        if (!hasNewDeploy) return;
        clearInterval(intervalInstanceRef.current);
      }, [hasNewDeploy]);
    
      useEffect(() => {
        if (!hasNewDeploy && windowFocused.current) {
          clearInterval(intervalInstanceRef.current);
          intervalInstanceRef.current = startInterval();
        }
        const onFocus = () => {
          debug('focus');
          windowFocused.current = true;
          clearInterval(intervalInstanceRef.current);
          intervalInstanceRef.current = startInterval();
        };
        const onBlur = () => {
          debug('blur');
          windowFocused.current = false;
          clearInterval(intervalInstanceRef.current);
        };
        debug('addEventListeners');
        window.addEventListener('focus', onFocus);
        window.addEventListener('blur', onBlur);
    
        return () => {
          debug('removeEventListeners');
          window.removeEventListener('focus', onFocus);
          window.removeEventListener('blur', onBlur);
        };
      }, []);
    
      useEffect(() => {
        const fetchInitialVersion = async () => {
          debug('Fetching initial version');
          const { version } = await getCurrentVersion(endpoint);
          if (version === 'unknown') {
            console.warn(
              '[next-deploy-notifications] Could not find current app version.',
            );
          } else {
            debug(`Version ${version}`);
            setCurrentVersion(version);
            lastFetchedRef.current = Date.now();
          }
        };
    
        fetchInitialVersion();
      }, [endpoint, debug]);
    
      return {
        hasNewDeploy,
        version: currentVersion,
      };
    };
    
    export { useHasNewDeploy };
    
    
    opened by sapkra 2
Releases(v0.1.6)
Owner
Ryan Toronto
Ryan Toronto
A GitHub app to report failed workflow job actions and notify pull request creator with custom report message for the failed workflow job.

Workflow Reporter A GitHub App built with Probot that reports failed workflow job actions and notify the pull request creator with custom report messa

Divyanshu Shekhar 14 Nov 12, 2022
Get a desktop notification every time a new correction slot is available for your 42 project.

42_slot_watcher A simple node.js corrections slots watcher for 42, working on Windows - MacOS - Linux. What is this I was bored of having to refresh t

Maxime 7 Dec 20, 2022
Based on Google Chrome recorder, implement UI interface capture and notify the result to the target mailbox

chrome-recoder-crawler README-CN Modify the .js file exported by Google Chrome recorder. By default, the innerText property of the node operated in th

wudu 4 Oct 18, 2022
Detect webpage updates and notify user to reload. support vite and umijs

English | 简体中文 plugin-web-update-notification Detect webpage updates and notify user to reload. support vite and umijs. Take the git commit hash as th

Utopia 57 Dec 26, 2022
A jQuery plug-in to notify you of CSS, Attribute or Property changes in an element

selectWatch.js jQuery plug-in gives an opportunity to monitor changes of DOM element's CSS styles, attributes, properties, input element or select ele

Fatih Kazancı 3 Oct 28, 2022
This is just a script I put together to check and notify me via email (MailGun) when there's an earlier date before my initial appointment date. It doesn't handle rescheduling.

US-visa-appointment-notifier This is just a script I put together to check and notify me via email (MailGun) when there's an earlier date before my in

Theophilus Omoregbee 13 Jan 4, 2023
Node.js script to notify stake data with Notifi Network

Created by Timur Ruziev (participant of stakewars-iii) You can see my challenge report here: https://github.com/ruziev-dev/near-stakewars-iii Getting

Timur Ruziev 6 Sep 6, 2022
Twitter like notify bar

jQuery Notify bar Please visit the project page for feedback and other details. Simple plugin (basically it's not a plugin, but widget) to show notify

Dmitri Smirnov 127 May 8, 2022
A map for 1337 Khouribga's new labs clusters. This tool will help 1337 students find available posts, and search for other students in the cluster by name or login.

1337KH Labs Clusters Map Hellow. This tool is made by 1337 Khouribga students for 1337 Khouribga students to help make their lives at the school easie

Oussama 18 Aug 8, 2022
GameLand is an online gaming web application that allows users to view different kind of games available and share their views on each game.

GameLand is an online gaming web application that allows users to view different kind of games available and share their views on each game.Users can like and make reservations to play online. Built with HTML/CSS , JAVASCRIPT,API.

tarike bouari 6 Sep 9, 2022
The app's backend is written in Python (Flask) and for search it uses Elasticsearch. I used this app as candidate application for learning out how to build, run and deploy a multi-container environment (docker-compose).

foodtrucks-app-docker-compose The app's backend is written in Python (Flask) and for search it uses Elasticsearch. I used this app as candidate applic

Selçuk Şan 3 Oct 24, 2022
This tool allows you to test your chains.json file to see if your chains are available, syncing, or in sync.

Chains Tester This tool allows you to test your chains.json file to see if your chains are available, syncing, or in sync. This is an open source tool

Jorge S. Cuesta 9 Nov 4, 2022
A health-focused app for users to be able to track workouts and nutritional data with a social media component to inspire friendly competition among the users.

A health-focused app for users to be able to track workouts and nutritional data with a social media component to inspire friendly competition among the users.

Jon Jackson 3 Aug 26, 2022
This project is a To-do list app which users can store and edit their Todo Tasks. Users can also change the order of their todo

Project This project is about a todo app bundling using webpack Additional description about the project and its features. Built With HTML CSS Javascr

Richmond Adu-Kyere 2 Jun 17, 2022
Awesome books app is a basic website that allows users to add/remove books from a list. It is a single page app (SPA) which allow switching to different pages of the app without page load. Built with JavaScript.

Awesome Books ES6 In this project, I build a basic website that allows users to add/remove books from a list. using ES6 syntax and make it more organi

Abdulhamid 11 Jul 1, 2022
ToDo list for your GitHub notifications. Available on MacOS.

GitToDo Streamline your workflow, stay on top of issues and pull requests. ToDo list for your GitHub notifications. Available on MacOS. Features Menu

Rushat Gabhane 2 Jun 14, 2022