Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement a way to insert content script in the middle of a page [RFC] #1010

Open
3 of 4 tasks
mfissehaye opened this issue Jun 23, 2024 · 1 comment
Open
3 of 4 tasks
Labels
enhancement New feature or request

Comments

@mfissehaye
Copy link

How do you envision this feature/change to look/work like?

The framework should allow react developer to be able to insert React components in the middle of the page instead of just being able to create an overlay

What is the purpose of this change/feature? Why?

Sometimes I want to be able to add the content after a button or below a div to improve user experience.

(OPTIONAL) Example implementations

For example adding more context to a specific portion of the page in a facebook feed, add a component (UI styled with tailwind let's say) after every other post.

(OPTIONAL) Contribution

  • I would like to contribute to this RFC via a PR

Verify canary release

  • I verified that the issue exists in plasmo canary release

Code of Conduct

  • I agree to follow this project's Code of Conduct
  • I checked the current issues for duplicate problems.
@mfissehaye mfissehaye added the enhancement New feature or request label Jun 23, 2024
@muzammil0011
Copy link

Currently this feature is not supported in Plasmo, But you can achieve this functionality using Mutation Observer to observe the element and then add whatever you want before or after that element.

Here is an example of the code that uses Arrive.js (provides events to watch for DOM elements creation and removal) that helped me:

import cssText from "data-text:~/contents/style.css"
import type { PlasmoCSConfig, PlasmoGetShadowHostId } from "plasmo"

import "arrive"

import { useEffect } from "react"
import { createRoot } from "react-dom/client"

export const config: PlasmoCSConfig = {
  matches: ["*://*.example.com/*"]
}

const HOST_ID = "engage-csui"

export const getShadowHostId: PlasmoGetShadowHostId = () => HOST_ID

export const getStyle = () => {
  const style = document.createElement("style")
  style.textContent = cssText
  return style
}

export default () => {
  useEffect(() => {
    const elementSelector = "#selected-element-selector"
    // Wait for the element to be added to the DOM
    document.arrive(elementSelector, function (element) {
      const buttonContainer = document.createElement("div")
      createRoot(buttonContainer).render(<>{/* <AnyReactComponent/> */}</>)
      element.insertBefore(buttonContainer, element.firstChild)
    })

    return () => {
      document.unbindArrive(elementSelector)
    }
  }, [])
  return <>{/* Element you want to add as overlay */}</>
}

You also have to declare arrive in globals.d.ts

declare global {
    interface Document {
      arrive(
        selector: string,
        options: any,
        callback: (element: Element) => void
      ): void
      arrive(selector: string, callback: (element: Element) => void): void
      unbindArrive(selector: string): void
    }
  }
  
  export {}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants