Add custom widgets blog post
parent
77106e596e
commit
9f3b0af22b
|
@ -0,0 +1,117 @@
|
|||
---
|
||||
title: Creating Your Own Custom Widgets for Renewed Tab
|
||||
author: rubenwardy
|
||||
layout: post
|
||||
description: >-
|
||||
Renewed Tab allows you to create custom widgets with your own UI and code,
|
||||
isolated from the rest of the extension to improve user privacy.
|
||||
images:
|
||||
cover:
|
||||
path: howto-custom/cover.png
|
||||
edit_iframe:
|
||||
path: howto-custom/edit_iframe.png
|
||||
caption: The Edit Widget modal dialog
|
||||
widget:
|
||||
path: howto-custom/widget.png
|
||||
caption: The Custom Widget
|
||||
---
|
||||
|
||||
Renewed Tab intends to be highly customisable whilst having a good user
|
||||
experience. Taken to the extreme, these two things are in conflict; the more
|
||||
features you add, the harder it is to provide a good user experience. Renewed
|
||||
Tab can't support every use case by itself - there's so much you could want to
|
||||
support, and so little time. It would also make the download huge.
|
||||
|
||||
The solution to this is to allow custom user content. By making it easy for
|
||||
users and third-party developers to create their own widgets and functionality,
|
||||
it becomes possible to support a lot more without increasing complexity.
|
||||
|
||||
Renewed Tab allows you to create custom widgets using the IFrame widget. IFrames
|
||||
isolate third-party code and UIs, protecting the user's privileged information
|
||||
such as bookmarks and recent sites. Most browser extension stores prohibit
|
||||
remote code, so using an IFrame is a requirement. This does impose some limits
|
||||
on what is possible in custom widgets - you are limited to your widgets, and
|
||||
can't change the UI elsewhere.
|
||||
|
||||
Please note that this is still **experimental** and a bit manual. In the future,
|
||||
we plan to improve support for third-party widgets, making it easier for users
|
||||
to use them and allowing more integration with the built-in UI.
|
||||
|
||||
<!-- more -->
|
||||
|
||||
- [Hello World widget](#hello-world-widget)
|
||||
- [Get the repository](#get-the-repository)
|
||||
- [Serving on localhost](#serving-on-localhost)
|
||||
- [Adding to Renewed Tab](#adding-to-renewed-tab)
|
||||
- [Distributing the Widget](#distributing-the-widget)
|
||||
- [Conclusion](#conclusion)
|
||||
|
||||
## Hello World widget
|
||||
|
||||
Renewed Tab uses the React framework, but you're free to use whatever framework
|
||||
you like. We will be using React in this tutorial. We recommend using Renewed
|
||||
Tab's CSS as a basis, however, to keep a consistent theme.
|
||||
|
||||
### Get the repository
|
||||
|
||||
Clone or download [our React widget template](https://gitlab.com/renewedtab/custom_widget_template):
|
||||
|
||||
git clone https://gitlab.com/renewedtab/custom_widget_template
|
||||
|
||||
Run `npm install` to install the dependencies.
|
||||
|
||||
### Serving on localhost
|
||||
|
||||
Renewed Tab can't access files on your computer. In order to add your custom
|
||||
widget to Renewed Tab, you'll need to make it available using a server of some
|
||||
kind. The best way to do this locally for testing is using something called a
|
||||
live HTTP server. Our example template uses webpack-dev-server for this purpose.
|
||||
|
||||
Run `npm start` to build the app and start the live server at
|
||||
<http://localhost:8080>. Once this is done, open it in your browser to check
|
||||
that it works.
|
||||
|
||||
### Adding to Renewed Tab
|
||||
|
||||
Now that you have a working live server, you can add your widget to your Renewed
|
||||
Tab install. If you don't want to change your browser's New Tab for this, you
|
||||
can use the [online version](https://web.renewedtab.com/).
|
||||
|
||||
Enter edit mode by clicking the pencil in the bottom right, click "+ Add
|
||||
Widget", then click "IFrame". Find the new IFrame, hover over it, and click the
|
||||
pencil to open the Edit IFrame model.
|
||||
|
||||
{% include figure.html img=page.images.edit_iframe %}
|
||||
|
||||
Set the URL to `http://localhost:8080`. You'll also probably also want to check
|
||||
"Show panel background".
|
||||
|
||||
Press OK, you should now see the widget. Try resizing and moving the widget,
|
||||
it should adapt to the available space.
|
||||
|
||||
{% include figure.html img=page.images.widget %}
|
||||
|
||||
|
||||
## Distributing the Widget
|
||||
|
||||
Run `npm run build` to build the widget. Share the `dist/` folder publicly to
|
||||
distribute your widget. A good way to do this is using GitLab pages, as it
|
||||
supports updating a static website using CI.
|
||||
|
||||
See the `.gitlab-ci.yml` of the template. It deploys the widget to
|
||||
<https://renewedtab.gitlab.io/custom_widget_template/>.
|
||||
|
||||
|
||||
|
||||
## Conclusion
|
||||
|
||||
Whilst support for custom widgets is in its early days, it's still possible to
|
||||
do a lot of cool things with it.
|
||||
|
||||
In the future, we'll be adding an official plugins API which will make it super
|
||||
easy to add custom widgets to Renewed Tab. Users will be able to find plugins in
|
||||
the settings menu or add them by URL. Plugins will be able to add widgets to the
|
||||
"Add Widgets" menu.
|
||||
|
||||
Make sure to share any creations you make on Twitter (#renewedtab), Discord, or
|
||||
Matrix. See [Get Involved](/get_involved).
|
|
@ -0,0 +1,94 @@
|
|||
|
||||
code {
|
||||
padding: .2em .4em;
|
||||
margin: 0;
|
||||
font-size: 85%;
|
||||
background-color: rgba(110,118,129,0.4);
|
||||
border-radius: 6px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
margin: 0 0 1em 0;
|
||||
}
|
||||
|
||||
.highlight code {
|
||||
padding: unset;
|
||||
background-color: unset;
|
||||
border-radius: unset;
|
||||
}
|
||||
|
||||
|
||||
/*! Darcula theme; https://github.com/alem0lars/vim-colorscheme-darcula */
|
||||
|
||||
|
||||
.highlight .hll { background-color: #ffffcc !important; }
|
||||
.highlight { color: #a9b7c6 !important; }
|
||||
.highlight .c { color: #808080 !important; font-style: italic !important; } /* Comment */
|
||||
.highlight .err { color: #a9b7c6 !important; } /* Error */
|
||||
.highlight .g { color: #a9b7c6 !important; } /* Generic */
|
||||
.highlight .k { color: #cc7832 !important; } /* Keyword */
|
||||
.highlight .l { color: #a9b7c6 !important; } /* Literal */
|
||||
.highlight .n, .highlight .h { color: #a9b7c6 !important; } /* Name */
|
||||
.highlight .o { color: #a9b7c6 !important; } /* Operator */
|
||||
.highlight .x { color: #a9b7c6 !important; } /* Other */
|
||||
.highlight .p { color: #a9b7c6 !important; } /* Punctuation */
|
||||
.highlight .cm { color: #808080 !important; font-style: italic !important; } /* Comment.Multiline */
|
||||
.highlight .cp { color: #cc7832 !important; } /* Comment.Preproc */
|
||||
.highlight .c1 { color: #808080 !important; font-style: italic !important; } /* Comment.Single */
|
||||
.highlight .cs { color: #808080 !important; font-style: italic !important; } /* Comment.Special */
|
||||
.highlight .gd { color: #8c0909 !important; } /* Generic.Deleted */
|
||||
.highlight .ge { color: #a9b7c6 !important; text-decoration: underline !important; } /* Generic.Emph */
|
||||
.highlight .gr { color: #a9b7c6 !important; } /* Generic.Error */
|
||||
.highlight .gh { color: #a9b7c6 !important; font-weight: bold !important; } /* Generic.Heading */
|
||||
.highlight .gi { color: #a9b7c6 !important; font-weight: bold !important; background-color: #47840d !important; } /* Generic.Inserted */
|
||||
.highlight .go { color: #bfbfbf !important; background-color: #313233 !important; } /* Generic.Output */
|
||||
.highlight .gp { color: #a9b7c6 !important; } /* Generic.Prompt */
|
||||
.highlight .gs { color: #a9b7c6 !important; } /* Generic.Strong */
|
||||
.highlight .gu { color: #a9b7c6 !important; font-weight: bold !important; } /* Generic.Subheading */
|
||||
.highlight .gt { color: #ffffff !important; background-color: #990000 !important; } /* Generic.Traceback */
|
||||
.highlight .kc { color: #cc7832 !important; } /* Keyword.Constant */
|
||||
.highlight .kd { color: #cc7832 !important; } /* Keyword.Declaration */
|
||||
.highlight .kn { color: #cc7832 !important; } /* Keyword.Namespace */
|
||||
.highlight .kp { color: #cc7832 !important; } /* Keyword.Pseudo */
|
||||
.highlight .kr { color: #cc7832 !important; } /* Keyword.Reserved */
|
||||
.highlight .kt { color: #cc7832 !important; } /* Keyword.Type */
|
||||
.highlight .ld { color: #a9b7c6 !important; } /* Literal.Date */
|
||||
.highlight .m { color: #6897bb !important; } /* Literal.Number */
|
||||
.highlight .s { color: #a5c25c !important; } /* Literal.String */
|
||||
.highlight .na { color: #ffc66d !important; } /* Name.Attribute */
|
||||
.highlight .nb { color: #cc7832 !important; } /* Name.Builtin */
|
||||
.highlight .nc { color: #a9b7c6 !important; } /* Name.Class */
|
||||
.highlight .no { color: #9876aa !important; } /* Name.Constant */
|
||||
.highlight .nd { color: #a9b7c6 !important; } /* Name.Decorator */
|
||||
.highlight .ni { color: #a9b7c6 !important; } /* Name.Entity */
|
||||
.highlight .ne { color: #a9b7c6 !important; } /* Name.Exception */
|
||||
.highlight .nf { color: #ffc66d !important; } /* Name.Function */
|
||||
.highlight .nl { color: #a5c25c !important; } /* Name.Label */
|
||||
.highlight .nn { color: #a9b7c6 !important; } /* Name.Namespace */
|
||||
.highlight .nx { color: #a9b7c6 !important; } /* Name.Other */
|
||||
.highlight .py { color: #a9b7c6 !important; } /* Name.Property */
|
||||
.highlight .nt { color: #cc7832 !important; } /* Name.Tag */
|
||||
.highlight .nv { color: #cc7832 !important; } /* Name.Variable */
|
||||
.highlight .ow { color: #cc7832 !important; } /* Operator.Word */
|
||||
.highlight .w { color: #a9b7c6 !important; } /* Text.Whitespace */
|
||||
.highlight .mf { color: #6897bb !important; } /* Literal.Number.Float */
|
||||
.highlight .mh { color: #6897bb !important; } /* Literal.Number.Hex */
|
||||
.highlight .mi { color: #6897bb !important; } /* Literal.Number.Integer */
|
||||
.highlight .mo { color: #6897bb !important; } /* Literal.Number.Oct */
|
||||
.highlight .sb { color: #a5c25c !important; } /* Literal.String.Backtick */
|
||||
.highlight .sc { color: #a5c25c !important; } /* Literal.String.Char */
|
||||
.highlight .sd { color: #a5c25c !important; } /* Literal.String.Doc */
|
||||
.highlight .s2 { color: #a5c25c !important; } /* Literal.String.Double */
|
||||
.highlight .se { color: #a5c25c !important; } /* Literal.String.Escape */
|
||||
.highlight .sh { color: #a5c25c !important; } /* Literal.String.Heredoc */
|
||||
.highlight .si { color: #a5c25c !important; } /* Literal.String.Interpol */
|
||||
.highlight .sx { color: #a5c25c !important; } /* Literal.String.Other */
|
||||
.highlight .sr { color: #a5c25c !important; } /* Literal.String.Regex */
|
||||
.highlight .s1 { color: #a5c25c !important; } /* Literal.String.Single */
|
||||
.highlight .ss { color: #a5c25c !important; } /* Literal.String.Symbol */
|
||||
.highlight .bp { color: #a9b7c6 !important; } /* Name.Builtin.Pseudo */
|
||||
.highlight .vc { color: #cc7832 !important; } /* Name.Variable.Class */
|
||||
.highlight .vg { color: #cc7832 !important; } /* Name.Variable.Global */
|
||||
.highlight .vi { color: #cc7832 !important; } /* Name.Variable.Instance */
|
||||
.highlight .il { color: #6897bb !important; } /* Literal.Number.Integer.Long */
|
|
@ -156,16 +156,7 @@ _wrong_. Please report it below.
|
|||
|
||||
## How do I add custom widgets?
|
||||
|
||||
We would really like to support custom widgets. But unfortunately, it's not
|
||||
possible due to the developer terms that Firefox and Chrome enforce on extension
|
||||
developers. We're not allowed to let users upload code which runs in the
|
||||
extension context.
|
||||
|
||||
GreaseMonkey is allowed because it runs on websites, not as an extension webpage.
|
||||
We'll continue to look for alternatives for this, as we'd really like to allow it.
|
||||
|
||||
What you can do is use an IFrame widget to show a webpage as if it were a widget.
|
||||
You can use this to create custom widgets.
|
||||
See [Creating Your Own Custom Widgets for Renewed Tab](/blog/2022/07/24/custom-widgets/).
|
||||
|
||||
## How can I get in contact?
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ redirect_from:
|
|||
- [¿Por qué no admite sincronización de navegador?](#por-qué-no-admite-sincronización-de-navegador)
|
||||
- [¿Por qué no está disponible para X navegador?](#por-qué-no-está-disponible-para-x-navegador)
|
||||
- [¿Por qué me sale un error al ingresar una URL personalizada en la versión web?](#por-qué-me-sale-un-error-al-ingresar-una-url-personalizada-en-la-versión-web)
|
||||
- [How do I add custom widgets?](#how-do-i-add-custom-widgets)
|
||||
- [Solicitudes de Funciones, Informe de Errores, y Asistencia](#solicitudes-de-funciones-informe-de-errores-y-asistencia)
|
||||
|
||||
|
||||
|
@ -142,6 +143,11 @@ Nota: Si obtiene el error mientras usa la extensión del navegador, hay algo
|
|||
_incorrecto_. Por favor repórtelo a continuación.
|
||||
|
||||
|
||||
## How do I add custom widgets?
|
||||
|
||||
See [Creating Your Own Custom Widgets for Renewed Tab](/blog/2022/07/24/custom-widgets/).
|
||||
|
||||
|
||||
## Solicitudes de Funciones, Informe de Errores, y Asistencia
|
||||
|
||||
Publicar un issue en el rastreador de problemas es la forma preferida de discutir
|
||||
|
|
|
@ -158,16 +158,8 @@ _wrong_. Please report it below.
|
|||
|
||||
## How do I add custom widgets?
|
||||
|
||||
We would really like to support custom widgets. But unfortunately, it's not
|
||||
possible due to the developer terms that Firefox and Chrome enforce on extension
|
||||
developers. We're not allowed to let users upload code which runs in the
|
||||
extension context.
|
||||
See [Creating Your Own Custom Widgets for Renewed Tab](/blog/2022/07/24/custom-widgets/).
|
||||
|
||||
GreaseMonkey is allowed because it runs on websites, not as an extension webpage.
|
||||
We'll continue to look for alternatives for this, as we'd really like to allow it.
|
||||
|
||||
What you can do is use an IFrame widget to show a webpage as if it were a widget.
|
||||
You can use this to create custom widgets.
|
||||
|
||||
## How can I get in contact?
|
||||
|
||||
|
|
|
@ -158,16 +158,7 @@ _wrong_. Please report it below.
|
|||
|
||||
## How do I add custom widgets?
|
||||
|
||||
We would really like to support custom widgets. But unfortunately, it's not
|
||||
possible due to the developer terms that Firefox and Chrome enforce on extension
|
||||
developers. We're not allowed to let users upload code which runs in the
|
||||
extension context.
|
||||
|
||||
GreaseMonkey is allowed because it runs on websites, not as an extension webpage.
|
||||
We'll continue to look for alternatives for this, as we'd really like to allow it.
|
||||
|
||||
What you can do is use an IFrame widget to show a webpage as if it were a widget.
|
||||
You can use this to create custom widgets.
|
||||
See [Creating Your Own Custom Widgets for Renewed Tab](/blog/2022/07/24/custom-widgets/).
|
||||
|
||||
## How can I get in contact?
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 537 KiB |
Binary file not shown.
After Width: | Height: | Size: 999 KiB |
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
|
@ -4,3 +4,4 @@
|
|||
@import "bulma";
|
||||
@import "buttons";
|
||||
@import "main";
|
||||
@import "syntax";
|
||||
|
|
Loading…
Reference in New Issue